Decompiled source of HolsteredItemPositions v1.2.2

BepInEx/plugins/HolsteredItemPositions.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using Dawn.Utils;
using FirstPersonView;
using GameNetcodeStuff;
using HarmonyLib;
using HolsteredItemPositions.Compat;
using HolsteredItemPositions.Monobehaviours;
using HolsteredItemPositions.NetcodePatcher;
using HolsteredItemPositions.Network;
using HolsteredItemPositions.Patches;
using HolsteredItemPositions.UIBehaviours;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Data;
using ReservedItemSlotCore.Patches;
using TMPro;
using TooManyEmotes.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.ProBuilder;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HolsteredItemPositions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyInformationalVersion("1.2.2")]
[assembly: AssemblyProduct("HolsteredItemPositions")]
[assembly: AssemblyTitle("HolsteredItemPositions")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HolsteredItemPositions
{
	internal static class ConfigManager
	{
		internal static ConfigEntry<bool> DebugLogsEnabled = null;

		internal static ConfigEntry<bool> SetupHudEnabled = null;

		internal static ConfigEntry<bool> ShowItemsOnMaskedEnemies = null;

		internal static readonly Dictionary<PlayerBone, ConfigEntry<bool>> FirstPersonBoneVisibility = new Dictionary<PlayerBone, ConfigEntry<bool>>();
	}
	internal class HolsteredItemPosition
	{
		[JsonProperty("bone")]
		internal PlayerBone Bone { get; set; }

		[JsonProperty("position")]
		internal Vector3 Position { get; set; }

		[JsonProperty("rotation")]
		internal Vector3 Rotation { get; set; }

		[JsonProperty("scale")]
		internal Vector3 Scale { get; set; } = Vector3.one;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		internal bool Disabled { get; set; }

		internal HolsteredItemPosition()
		{
		}//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)


		internal HolsteredItemPosition(HolsteredItemPosition position)
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Bone = position.Bone;
			Position = position.Position;
			Rotation = position.Rotation;
			Scale = position.Scale;
		}
	}
	internal static class Log
	{
		internal static void Debug(string message)
		{
			if (ConfigManager.DebugLogsEnabled.Value)
			{
				Write((LogLevel)32, message);
			}
		}

		internal static void Info(string message)
		{
			Write((LogLevel)16, message);
		}

		internal static void Warn(string message)
		{
			Write((LogLevel)4, message);
		}

		internal static void Error(string message)
		{
			Write((LogLevel)2, message);
		}

		internal static void Fatal(string message)
		{
			Write((LogLevel)1, message);
		}

		private static void Write(LogLevel logLevel, string message)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Plugin.mls.Log(logLevel, (object)message);
		}
	}
	internal enum PlayerBone
	{
		Hips,
		Spine1,
		Spine2,
		Spine3,
		Neck,
		Head,
		LeftShoulder,
		LeftArmUpper,
		LeftArmLower,
		LeftHand,
		RightShoulder,
		RightArmUpper,
		RightArmLower,
		RightHand,
		LeftThigh,
		LeftCalf,
		LeftFoot,
		LeftHeel,
		LeftToe,
		RightThigh,
		RightCalf,
		RightFoot,
		RightHeel,
		RightToe
	}
	[BepInPlugin("HQ_Team.HolsteredItemPositions", "HolsteredItemPositions", "1.2.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string modGUID = "HQ_Team.HolsteredItemPositions";

		internal const string modName = "HolsteredItemPositions";

		internal const string modVersion = "1.2.2";

		internal static ManualLogSource mls;

		private Harmony _harmony;

		internal static GameObject NetworkPrefab { get; private set; }

		internal static GameObject HUDPrefab { get; private set; }

		internal static bool HasFirstPersonView { get; private set; }

		internal static bool HasReservedItemSlotCore { get; private set; }

		internal static bool HasTooManyEmotes { get; private set; }

		private void Awake()
		{
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			mls = ((BaseUnityPlugin)this).Logger;
			ConfigManager.DebugLogsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Internal", "Enable Debug Logging", false, "Enables debug logging");
			ConfigManager.SetupHudEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Setup HUD", false, "Loads the setup HUD and can be opened ingame after pressing F10");
			ConfigManager.ShowItemsOnMaskedEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Items On Masked Enemies", true, "Shows a player's holstered items on masked enemies mimicking them");
			foreach (PlayerBone value in Enum.GetValues(typeof(PlayerBone)))
			{
				ConfigManager.FirstPersonBoneVisibility[value] = ((BaseUnityPlugin)this).Config.Bind<bool>("First Person View Compatibility", value.ToString(), true, $"Shows items holstered on the {value} bone while using FirstPersonView");
			}
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<HolsteredItemEntry>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<HolsteredItemEntry>();
			((Registry<DawnItemInfo>)(object)LethalContent.Items).OnFreeze += PositionConfig.Load;
			if (((Registry<DawnItemInfo>)(object)LethalContent.Items).IsFrozen)
			{
				PositionConfig.Load();
			}
			try
			{
				AssetBundle val = AssetBundleUtils.LoadBundle(typeof(Plugin).Assembly, "holstereditempositionsassets");
				if ((Object)(object)val != (Object)null)
				{
					GameObject val2 = val.LoadAsset<GameObject>("HolsteredItemPositionsNetwork");
					if ((Object)(object)val2 != (Object)null)
					{
						val2.AddComponent<HolsteredItemNetwork>();
						DawnLib.RegisterNetworkPrefab(val2);
						NetworkPrefab = val2;
					}
				}
			}
			catch (Exception arg)
			{
				Log.Error($"Network prefab asset bundle loading failed: {arg}");
			}
			if (ConfigManager.SetupHudEnabled.Value)
			{
				try
				{
					AssetBundle val3 = AssetBundleUtils.LoadBundle(typeof(Plugin).Assembly, "holstereditempositionshud");
					if ((Object)(object)val3 != (Object)null)
					{
						GameObject val4 = val3.LoadAsset<GameObject>("HolsteredItemPositionsHUD");
						if ((Object)(object)val4 != (Object)null)
						{
							HUDPrefab = val4;
						}
					}
				}
				catch (Exception arg2)
				{
					Log.Error($"Setup HUD asset bundle loading failed: {arg2}");
				}
			}
			_harmony = new Harmony("HQ_Team.HolsteredItemPositions");
			_harmony.PatchAll(typeof(FlashlightItemPatches));
			_harmony.PatchAll(typeof(GameNetworkManagerPatches));
			_harmony.PatchAll(typeof(GrabbableObjectPatches));
			_harmony.PatchAll(typeof(HauntedMaskItemPatches));
			_harmony.PatchAll(typeof(HUDManagerPatches));
			_harmony.PatchAll(typeof(EnemyAIPatches));
			_harmony.PatchAll(typeof(MaskedPlayerEnemyPatches));
			_harmony.PatchAll(typeof(PlayerControllerBPatches));
			_harmony.PatchAll(typeof(StartOfRoundPatches));
			HasFirstPersonView = Chainloader.PluginInfos.ContainsKey("com.seeya.firstpersonview");
			HasReservedItemSlotCore = Chainloader.PluginInfos.ContainsKey("FlipMods.ReservedItemSlotCore");
			if (HasReservedItemSlotCore)
			{
				_harmony.PatchAll(typeof(ReservedItemSlotCoreCompat));
			}
			HasTooManyEmotes = Chainloader.PluginInfos.ContainsKey("FlipMods.TooManyEmotes");
			if (HasTooManyEmotes)
			{
				_harmony.PatchAll(typeof(TooManyEmotesCompat));
			}
			Log.Info("HolsteredItemPositions loaded");
		}
	}
	internal static class PositionConfig
	{
		internal static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
		{
			Converters = { (JsonConverter)new NamespacedKeyDictionaryConverter() },
			Converters = { (JsonConverter)new Vector3Converter() },
			Converters = { (JsonConverter)new StringEnumConverter() }
		};

		private static Dictionary<NamespacedKey, HolsteredItemPosition> positions = new Dictionary<NamespacedKey, HolsteredItemPosition>();

		private static Dictionary<NamespacedKey, HolsteredItemPosition> defaultPositions = new Dictionary<NamespacedKey, HolsteredItemPosition>();

		private static readonly Dictionary<NamespacedKey, string> positionFiles = new Dictionary<NamespacedKey, string>();

		private static readonly Dictionary<string, HashSet<NamespacedKey>> positionEntries = new Dictionary<string, HashSet<NamespacedKey>>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<NamespacedKey> disabledPositions = new HashSet<NamespacedKey>();

		private static readonly HashSet<string> itemsWithoutDawnInfo = new HashSet<string>();

		private static bool loaded;

		internal static readonly string DirectoryPath = Path.Combine(Paths.ConfigPath, "HolsteredItemPositions");

		internal static readonly string DefaultFilePath = Path.Combine(DirectoryPath, "HolsteredItemPositions.json");

		internal static readonly string CustomFilePath = Path.Combine(DirectoryPath, "CustomHolsteredItemPositions.json");

		internal static bool IsLoaded => loaded;

		internal static HolsteredItemPosition? PositionFor(Item item)
		{
			if (!loaded)
			{
				return null;
			}
			DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(item);
			if (dawnInfo == null)
			{
				if (itemsWithoutDawnInfo.Add(item.itemName))
				{
					Log.Warn("Namespaced key was not found for " + item.itemName + ", holster position skipped.");
				}
				return null;
			}
			positions.TryGetValue(((DawnBaseInfo<DawnItemInfo>)(object)dawnInfo).Key, out HolsteredItemPosition value);
			return value;
		}

		internal static string FileFor(Item item)
		{
			NamespacedKey key = ((DawnBaseInfo<DawnItemInfo>)(object)ItemExtensions.GetDawnInfo(item)).Key;
			if (positionFiles.ContainsKey(key))
			{
				return Path.GetFileName(positionFiles[key]);
			}
			return string.Empty;
		}

		internal static bool IsDisabled(Item item)
		{
			return disabledPositions.Contains(((DawnBaseInfo<DawnItemInfo>)(object)ItemExtensions.GetDawnInfo(item)).Key);
		}

		internal static bool EntryInFile(NamespacedKey key, string path)
		{
			if (positionEntries.TryGetValue(path, out HashSet<NamespacedKey> value))
			{
				return value.Contains(key);
			}
			return false;
		}

		internal static bool Delete(NamespacedKey key, string path)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Directory.CreateDirectory(DirectoryPath);
			JObject val = (JObject)((!File.Exists(path)) ? ((object)new JObject()) : ((object)JObject.Parse(File.ReadAllText(path))));
			bool flag = val.Remove(((object)key).ToString());
			if (!flag)
			{
				val[((object)key).ToString()] = (JToken)new JObject { ["disabled"] = JToken.op_Implicit(true) };
			}
			File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>()) + Environment.NewLine);
			Load();
			return flag;
		}

		internal static void Save(Dictionary<NamespacedKey, HolsteredItemPosition> edits, string path)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			Directory.CreateDirectory(DirectoryPath);
			JObject val = (JObject)((!File.Exists(path)) ? ((object)new JObject()) : ((object)JObject.Parse(File.ReadAllText(path))));
			JsonSerializer val2 = JsonSerializer.Create(JsonSettings);
			foreach (KeyValuePair<NamespacedKey, HolsteredItemPosition> edit in edits)
			{
				HolsteredItemPosition holsteredItemPosition = new HolsteredItemPosition(edit.Value)
				{
					Position = new Vector3(Mathf.Round(edit.Value.Position.x * 100f) * 0.01f, Mathf.Round(edit.Value.Position.y * 100f) * 0.01f, Mathf.Round(edit.Value.Position.z * 100f) * 0.01f),
					Rotation = new Vector3(Mathf.Round(edit.Value.Rotation.x * 100f) * 0.01f, Mathf.Round(edit.Value.Rotation.y * 100f) * 0.01f, Mathf.Round(edit.Value.Rotation.z * 100f) * 0.01f),
					Scale = new Vector3(Mathf.Round(edit.Value.Scale.x * 100f) * 0.01f, Mathf.Round(edit.Value.Scale.y * 100f) * 0.01f, Mathf.Round(edit.Value.Scale.z * 100f) * 0.01f)
				};
				val[((object)edit.Key).ToString()] = (JToken)(object)JObject.FromObject((object)holsteredItemPosition, val2);
			}
			File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>()) + Environment.NewLine);
			Load();
		}

		internal static void Load()
		{
			loaded = true;
			try
			{
				Directory.CreateDirectory(DirectoryPath);
				if (!File.Exists(DefaultFilePath))
				{
					File.WriteAllText(DefaultFilePath, "{}" + Environment.NewLine);
					Log.Info("HolsteredItemPositions.json created");
				}
				if (!File.Exists(CustomFilePath))
				{
					File.WriteAllText(CustomFilePath, "{}" + Environment.NewLine);
					Log.Info("CustomHolsteredItemPositions.json created");
				}
				defaultPositions = ReadPositions(DefaultFilePath, allowDisabled: false);
				positions = new Dictionary<NamespacedKey, HolsteredItemPosition>(defaultPositions);
				positionFiles.Clear();
				positionEntries.Clear();
				disabledPositions.Clear();
				HashSet<NamespacedKey> hashSet = new HashSet<NamespacedKey>();
				foreach (NamespacedKey key2 in defaultPositions.Keys)
				{
					hashSet.Add(key2);
				}
				positionEntries.Add(DefaultFilePath, hashSet);
				foreach (NamespacedKey key3 in defaultPositions.Keys)
				{
					positionFiles.Add(key3, DefaultFilePath);
				}
				string[] files = Directory.GetFiles(DirectoryPath, "*.json", SearchOption.TopDirectoryOnly);
				Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
				List<string> list = new List<string>(1) { CustomFilePath };
				string[] array = files;
				foreach (string text in array)
				{
					if (!string.Equals(text, DefaultFilePath, StringComparison.OrdinalIgnoreCase) && !string.Equals(text, CustomFilePath, StringComparison.OrdinalIgnoreCase))
					{
						list.Add(text);
					}
				}
				Dictionary<NamespacedKey, string> dictionary = new Dictionary<NamespacedKey, string>();
				foreach (string item in list)
				{
					Dictionary<NamespacedKey, HolsteredItemPosition> dictionary2 = ReadPositions(item, allowDisabled: true);
					string key = item;
					HashSet<NamespacedKey> hashSet2 = new HashSet<NamespacedKey>();
					foreach (NamespacedKey key4 in dictionary2.Keys)
					{
						hashSet2.Add(key4);
					}
					positionEntries.Add(key, hashSet2);
					foreach (KeyValuePair<NamespacedKey, HolsteredItemPosition> item2 in dictionary2)
					{
						if (dictionary.TryGetValue(item2.Key, out var value))
						{
							Log.Warn($"Custom holster position {item2.Key} is present in {Path.GetFileName(value)} and {Path.GetFileName(item)}. Using {Path.GetFileName(value)}.");
							continue;
						}
						dictionary.Add(item2.Key, item);
						if (item2.Value.Disabled)
						{
							positions.Remove(item2.Key);
							positionFiles[item2.Key] = item;
							disabledPositions.Add(item2.Key);
						}
						else
						{
							positions[item2.Key] = item2.Value;
							positionFiles[item2.Key] = item;
							disabledPositions.Remove(item2.Key);
						}
					}
				}
				Log.Info($"Loaded {positions.Count} holster positions");
			}
			catch (Exception arg)
			{
				positions.Clear();
				defaultPositions.Clear();
				positionFiles.Clear();
				positionEntries.Clear();
				disabledPositions.Clear();
				Log.Error($"Holster positions failed to load: {arg}");
			}
		}

		private static Dictionary<NamespacedKey, HolsteredItemPosition> ReadPositions(string path, bool allowDisabled)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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_018b: Invalid comparison between Unknown and I4
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Invalid comparison between Unknown and I4
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			string text = File.ReadAllText(path);
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			using StringReader stringReader = new StringReader(text);
			JsonTextReader val = new JsonTextReader((TextReader)stringReader);
			try
			{
				while (((JsonReader)val).Read())
				{
					if ((int)((JsonReader)val).TokenType == 4 && ((JsonReader)val).Depth == 1 && ((JsonReader)val).Value is string text2 && !hashSet.Add(text2) && hashSet2.Add(text2))
					{
						Log.Warn("Holster position " + text2 + " appears more than once in " + Path.GetFileName(path) + ". The last entry was used.");
					}
				}
				JObject val2 = JObject.Parse(text);
				List<string> list = new List<string>();
				JToken val5 = default(JToken);
				JToken token = default(JToken);
				foreach (JProperty item in val2.Properties())
				{
					NamespacedKey val3 = NamespacedKey.Parse(item.Name);
					if (((object)val3).ToString() != item.Name)
					{
						throw new JsonException("Invalid item key " + item.Name);
					}
					if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).ContainsKey(val3.AsTyped<DawnItemInfo>()))
					{
						list.Add(item.Name);
						Log.Debug("Namespaced key " + item.Name + " was not found, holster position skipped.");
						continue;
					}
					JToken value = item.Value;
					JObject val4 = (JObject)(object)((value is JObject) ? value : null);
					if (val4 == null)
					{
						throw new JsonException("Invalid position for " + item.Name);
					}
					bool flag = false;
					if (val4.TryGetValue("disabled", ref val5))
					{
						if (!allowDisabled || (int)val5.Type != 9)
						{
							throw new JsonException("Invalid position for " + item.Name);
						}
						flag = Extensions.Value<bool>((IEnumerable<JToken>)val5);
					}
					JToken val6 = val4["bone"];
					if (flag || (val6 != null && (int)val6.Type == 8 && Enum.TryParse<PlayerBone>(Extensions.Value<string>((IEnumerable<JToken>)val6), ignoreCase: false, out var result) && Enum.IsDefined(typeof(PlayerBone), result) && ValidVector(val4["position"]) && ValidVector(val4["rotation"]) && (!val4.TryGetValue("scale", ref token) || ValidVector(token))))
					{
						continue;
					}
					throw new JsonException("Invalid position for " + item.Name);
				}
				foreach (string item2 in list)
				{
					val2.Remove(item2);
				}
				return JsonConvert.DeserializeObject<Dictionary<NamespacedKey, HolsteredItemPosition>>(((object)val2).ToString(), JsonSettings) ?? throw new JsonException(Path.GetFileName(path) + " was empty");
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private static bool ValidVector(JToken? token)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0047: Invalid comparison between Unknown and I4
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Invalid comparison between Unknown and I4
			JObject val = (JObject)(object)((token is JObject) ? token : null);
			if (val == null)
			{
				return false;
			}
			JToken obj = val["x"];
			JTokenType? val2 = ((obj != null) ? new JTokenType?(obj.Type) : ((JTokenType?)null));
			bool flag;
			if (val2.HasValue)
			{
				JTokenType valueOrDefault = val2.GetValueOrDefault();
				if (valueOrDefault - 6 <= 1)
				{
					flag = true;
					goto IL_004f;
				}
			}
			flag = false;
			goto IL_004f;
			IL_00a2:
			bool flag3;
			bool flag2 = flag3;
			goto IL_00a6;
			IL_00a6:
			bool flag4 = flag2;
			if (flag4)
			{
				JToken obj2 = val["z"];
				JTokenType? val3 = ((obj2 != null) ? new JTokenType?(obj2.Type) : ((JTokenType?)null));
				if (val3.HasValue)
				{
					JTokenType valueOrDefault2 = val3.GetValueOrDefault();
					if (valueOrDefault2 - 6 <= 1)
					{
						flag3 = true;
						goto IL_00f6;
					}
				}
				flag3 = false;
				goto IL_00f6;
			}
			goto IL_00fa;
			IL_00fa:
			return flag4;
			IL_004f:
			bool flag5 = flag;
			flag2 = flag5;
			if (flag2)
			{
				JToken obj3 = val["y"];
				JTokenType? val3 = ((obj3 != null) ? new JTokenType?(obj3.Type) : ((JTokenType?)null));
				if (val3.HasValue)
				{
					JTokenType valueOrDefault2 = val3.GetValueOrDefault();
					if (valueOrDefault2 - 6 <= 1)
					{
						flag3 = true;
						goto IL_00a2;
					}
				}
				flag3 = false;
				goto IL_00a2;
			}
			goto IL_00a6;
			IL_00f6:
			flag4 = flag3;
			goto IL_00fa;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HolsteredItemPositions";

		public const string PLUGIN_NAME = "HolsteredItemPositions";

		public const string PLUGIN_VERSION = "1.2.2";
	}
}
namespace HolsteredItemPositions.UIBehaviours
{
	public class HolsterPreview : MonoBehaviour, IDragHandler, IEventSystemHandler, IScrollHandler
	{
		private enum RotationLock
		{
			Free,
			Vertical,
			Horizontal
		}

		[SerializeField]
		private Transform pivot;

		[SerializeField]
		private Camera previewCamera;

		[SerializeField]
		private Light previewLight;

		[SerializeField]
		private RawImage previewImage;

		[SerializeField]
		private Button resetButton;

		[SerializeField]
		private Button verticalRotationButton;

		[SerializeField]
		private Button horizontalRotationButton;

		[SerializeField]
		private Color rotationLockColor;

		[SerializeField]
		private float dragSpeed = 0.25f;

		[SerializeField]
		private float panSpeed = 0.005f;

		[SerializeField]
		private float zoomSpeed = 0.2f;

		[SerializeField]
		private float minDistance = 2f;

		[SerializeField]
		private float maxDistance = 8f;

		private readonly Dictionary<PlayerBone, Transform> bones = new Dictionary<PlayerBone, Transform>();

		private GameObject itemVisual;

		private Item selectedItem;

		private Quaternion startingRotation;

		private Vector3 startingCameraPosition;

		private float startingLightIntensity;

		private float startingCameraDistance;

		private Color verticalRotationColor;

		private Color horizontalRotationColor;

		private RotationLock rotationLock;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			startingRotation = pivot.localRotation;
			startingCameraPosition = ((Component)previewCamera).transform.localPosition;
			startingLightIntensity = previewLight.intensity;
			startingCameraDistance = Mathf.Abs(startingCameraPosition.z);
			verticalRotationColor = ((Selectable)verticalRotationButton).targetGraphic.color;
			horizontalRotationColor = ((Selectable)horizontalRotationButton).targetGraphic.color;
			((UnityEvent)resetButton.onClick).AddListener(new UnityAction(ResetView));
			((UnityEvent)verticalRotationButton.onClick).AddListener(new UnityAction(VerticalRotationClicked));
			((UnityEvent)horizontalRotationButton.onClick).AddListener(new UnityAction(HorizontalRotationClicked));
		}

		internal void Open(PlayerControllerB player)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)player).transform;
			GameObject val = new GameObject("PreviewRig")
			{
				layer = ((Component)pivot).gameObject.layer
			};
			val.transform.SetParent(pivot, false);
			val.transform.localScale = transform.localScale;
			Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform> { [transform] = val.transform };
			Transform[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)(object)transform))
				{
					GameObject val3 = new GameObject(((Object)val2).name)
					{
						layer = ((Component)pivot).gameObject.layer
					};
					Transform transform2 = val3.transform;
					transform2.SetParent(dictionary[val2.parent], false);
					transform2.SetLocalPositionAndRotation(val2.localPosition, val2.localRotation);
					transform2.localScale = val2.localScale;
					val3.SetActive(((Component)val2).gameObject.activeSelf);
					dictionary.Add(val2, transform2);
				}
			}
			SkinnedMeshRenderer thisPlayerModel = player.thisPlayerModel;
			Bounds bounds = ((Renderer)thisPlayerModel).bounds;
			Vector3 val4 = Vector3.Scale(transform.InverseTransformPoint(((Bounds)(ref bounds)).center), transform.localScale);
			Transform obj = pivot;
			obj.localPosition += pivot.localRotation * val4;
			val.transform.localPosition = -val4;
			Vector3 localPosition = ((Component)previewCamera).transform.localPosition;
			localPosition.x = pivot.localPosition.x;
			localPosition.y = pivot.localPosition.y;
			((Component)previewCamera).transform.localPosition = localPosition;
			startingCameraPosition = localPosition;
			SkinnedMeshRenderer val5 = ((Component)dictionary[((Component)thisPlayerModel).transform]).gameObject.AddComponent<SkinnedMeshRenderer>();
			val5.sharedMesh = thisPlayerModel.sharedMesh;
			((Renderer)val5).sharedMaterials = ((Renderer)thisPlayerModel).sharedMaterials;
			((Renderer)val5).localBounds = ((Renderer)thisPlayerModel).localBounds;
			val5.updateWhenOffscreen = true;
			Transform[] array = thisPlayerModel.bones;
			Transform[] array2 = (Transform[])(object)new Transform[array.Length];
			for (int j = 0; j < array.Length; j++)
			{
				array2[j] = dictionary[array[j]];
			}
			val5.bones = array2;
			val5.rootBone = dictionary[thisPlayerModel.rootBone];
			((Renderer)val5).enabled = true;
			previewImage.texture = (Texture)(object)previewCamera.targetTexture;
			Transform[] array3 = val5.bones;
			foreach (Transform val6 in array3)
			{
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				for (int l = 0; l < HolsterVisuals.BoneNames.Length; l++)
				{
					if (((Object)val6).name == HolsterVisuals.BoneNames[l])
					{
						bones.TryAdd((PlayerBone)l, val6);
					}
				}
			}
		}

		internal void Select(Item item, HolsteredItemPosition position)
		{
			//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)
			//IL_0047: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Invalid comparison between Unknown and I4
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Invalid comparison between Unknown and I4
			if ((Object)(object)itemVisual != (Object)null)
			{
				Object.Destroy((Object)(object)itemVisual);
			}
			selectedItem = item;
			itemVisual = new GameObject(item.itemName)
			{
				layer = ((Component)pivot).gameObject.layer
			};
			GameObject spawnPrefab = item.spawnPrefab;
			if ((Object)(object)spawnPrefab == (Object)null)
			{
				Log.Warn("Preview could not show " + item.itemName + " because its prefab is missing.");
				return;
			}
			Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform> { [spawnPrefab.transform] = itemVisual.transform };
			List<(SkinnedMeshRenderer, SkinnedMeshRenderer)> list = new List<(SkinnedMeshRenderer, SkinnedMeshRenderer)>();
			List<Animator> list2 = new List<Animator>();
			Transform[] componentsInChildren = spawnPrefab.GetComponentsInChildren<Transform>(true);
			ProBuilderMesh val3 = default(ProBuilderMesh);
			MeshFilter val4 = default(MeshFilter);
			MeshFilter val5 = default(MeshFilter);
			MeshRenderer val6 = default(MeshRenderer);
			SkinnedMeshRenderer val8 = default(SkinnedMeshRenderer);
			Animator val10 = default(Animator);
			foreach (Transform val in componentsInChildren)
			{
				Transform transform2;
				if ((Object)(object)val == (Object)(object)spawnPrefab.transform)
				{
					transform2 = itemVisual.transform;
				}
				else
				{
					GameObject val2 = new GameObject(((Object)val).name)
					{
						layer = ((Component)pivot).gameObject.layer
					};
					transform2 = val2.transform;
					transform2.SetParent(dictionary[val.parent], false);
					transform2.SetLocalPositionAndRotation(val.localPosition, val.localRotation);
					transform2.localScale = val.localScale;
					val2.SetActive(((Component)val).gameObject.activeSelf);
					dictionary.Add(val, transform2);
				}
				if (HolsterVisuals.IsExcludedMesh(val, spawnPrefab.transform, inPreview: true))
				{
					continue;
				}
				if (((Component)val).TryGetComponent<ProBuilderMesh>(ref val3) && ((Component)val).TryGetComponent<MeshFilter>(ref val4))
				{
					Mesh sharedMesh = val4.sharedMesh;
					bool flag = (Object)(object)sharedMesh == (Object)null;
					if ((Object)(object)sharedMesh != (Object)null)
					{
						flag = sharedMesh.vertexCount == 0;
					}
					if (flag)
					{
						val3.ToMesh((MeshTopology)0);
						val3.Refresh((RefreshMask)31);
					}
				}
				if (((Component)val).TryGetComponent<MeshFilter>(ref val5) && ((Component)val).TryGetComponent<MeshRenderer>(ref val6))
				{
					((Component)transform2).gameObject.AddComponent<MeshFilter>().sharedMesh = val5.sharedMesh;
					MeshRenderer val7 = ((Component)transform2).gameObject.AddComponent<MeshRenderer>();
					((Renderer)val7).sharedMaterials = ((Renderer)val6).sharedMaterials;
					((Renderer)val7).enabled = ((Renderer)val6).enabled;
				}
				if (((Component)val).TryGetComponent<SkinnedMeshRenderer>(ref val8))
				{
					SkinnedMeshRenderer val9 = ((Component)transform2).gameObject.AddComponent<SkinnedMeshRenderer>();
					val9.sharedMesh = val8.sharedMesh;
					((Renderer)val9).sharedMaterials = ((Renderer)val8).sharedMaterials;
					((Renderer)val9).localBounds = ((Renderer)val8).localBounds;
					((Renderer)val9).enabled = ((Renderer)val8).enabled;
					list.Add((val8, val9));
				}
				if (((Component)val).TryGetComponent<Animator>(ref val10))
				{
					Animator val11 = ((Component)transform2).gameObject.AddComponent<Animator>();
					val11.runtimeAnimatorController = val10.runtimeAnimatorController;
					val11.avatar = val10.avatar;
					val11.applyRootMotion = false;
					val11.cullingMode = (AnimatorCullingMode)0;
					list2.Add(val11);
				}
			}
			foreach (var item4 in list)
			{
				SkinnedMeshRenderer item2 = item4.Item1;
				SkinnedMeshRenderer item3 = item4.Item2;
				Transform[] array = item2.bones;
				Transform[] array2 = (Transform[])(object)new Transform[array.Length];
				for (int j = 0; j < array.Length; j++)
				{
					if ((Object)(object)array[j] != (Object)null && dictionary.TryGetValue(array[j], out var value))
					{
						array2[j] = value;
					}
				}
				item3.bones = array2;
				if ((Object)(object)item2.rootBone != (Object)null && dictionary.TryGetValue(item2.rootBone, out var value2))
				{
					item3.rootBone = value2;
				}
			}
			foreach (Animator item5 in list2)
			{
				item5.Rebind();
				AnimatorControllerParameter[] parameters = item5.parameters;
				foreach (AnimatorControllerParameter val12 in parameters)
				{
					if ((int)val12.type == 4)
					{
						item5.SetBool(val12.nameHash, false);
					}
					else if ((int)val12.type == 9)
					{
						item5.ResetTrigger(val12.nameHash);
					}
				}
				item5.Update(1f);
				((Behaviour)item5).enabled = false;
			}
			Place(position);
		}

		internal void Place(HolsteredItemPosition position)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)itemVisual == (Object)null) && !((Object)(object)selectedItem == (Object)null) && !((Object)(object)selectedItem.spawnPrefab == (Object)null))
			{
				if (!bones.TryGetValue(position.Bone, out Transform value))
				{
					itemVisual.SetActive(false);
					return;
				}
				itemVisual.SetActive(true);
				itemVisual.transform.SetParent(value, false);
				itemVisual.transform.localPosition = position.Position;
				itemVisual.transform.localEulerAngles = position.Rotation;
				Vector3 localScale = selectedItem.spawnPrefab.transform.localScale;
				Vector3 lossyScale = value.lossyScale;
				itemVisual.transform.localScale = new Vector3(localScale.x * position.Scale.x / lossyScale.x, localScale.y * position.Scale.y / lossyScale.y, localScale.z * position.Scale.z / lossyScale.z);
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!RectTransformUtility.RectangleContainsScreenPoint(((Graphic)previewImage).rectTransform, eventData.pressPosition, eventData.pressEventCamera))
			{
				return;
			}
			if ((int)eventData.button == 0)
			{
				if (rotationLock != RotationLock.Vertical)
				{
					pivot.Rotate(((Component)previewCamera).transform.up, (0f - eventData.delta.x) * dragSpeed, (Space)0);
				}
				if (rotationLock != RotationLock.Horizontal)
				{
					pivot.Rotate(((Component)previewCamera).transform.right, eventData.delta.y * dragSpeed, (Space)0);
				}
			}
			else if ((int)eventData.button == 2)
			{
				Vector3 val = ((Component)previewCamera).transform.right * ((0f - eventData.delta.x) * panSpeed);
				val += ((Component)previewCamera).transform.up * ((0f - eventData.delta.y) * panSpeed);
				Transform transform = ((Component)previewCamera).transform;
				transform.position += val;
			}
		}

		public void OnScroll(PointerEventData eventData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (RectTransformUtility.RectangleContainsScreenPoint(((Graphic)previewImage).rectTransform, eventData.position, eventData.enterEventCamera))
			{
				Vector3 localPosition = ((Component)previewCamera).transform.localPosition;
				float num = Mathf.Clamp(eventData.scrollDelta.y, -1f, 1f);
				localPosition.z = 0f - Mathf.Clamp(0f - localPosition.z - num * zoomSpeed, minDistance, maxDistance);
				((Component)previewCamera).transform.localPosition = localPosition;
				float num2 = Mathf.Abs(localPosition.z) / startingCameraDistance;
				previewLight.intensity = startingLightIntensity * num2 * num2;
			}
		}

		private void ResetView()
		{
			//IL_0007: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			pivot.localRotation = startingRotation;
			((Component)previewCamera).transform.localPosition = startingCameraPosition;
			previewLight.intensity = startingLightIntensity;
			rotationLock = RotationLock.Free;
			((Selectable)verticalRotationButton).targetGraphic.color = verticalRotationColor;
			((Selectable)horizontalRotationButton).targetGraphic.color = horizontalRotationColor;
		}

		private void VerticalRotationClicked()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (rotationLock == RotationLock.Vertical)
			{
				rotationLock = RotationLock.Free;
			}
			else
			{
				rotationLock = RotationLock.Vertical;
			}
			if (rotationLock == RotationLock.Vertical)
			{
				((Selectable)verticalRotationButton).targetGraphic.color = rotationLockColor;
			}
			else
			{
				((Selectable)verticalRotationButton).targetGraphic.color = verticalRotationColor;
			}
			((Selectable)horizontalRotationButton).targetGraphic.color = horizontalRotationColor;
		}

		private void HorizontalRotationClicked()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (rotationLock == RotationLock.Horizontal)
			{
				rotationLock = RotationLock.Free;
			}
			else
			{
				rotationLock = RotationLock.Horizontal;
			}
			if (rotationLock == RotationLock.Horizontal)
			{
				((Selectable)horizontalRotationButton).targetGraphic.color = rotationLockColor;
			}
			else
			{
				((Selectable)horizontalRotationButton).targetGraphic.color = horizontalRotationColor;
			}
			((Selectable)verticalRotationButton).targetGraphic.color = verticalRotationColor;
		}
	}
	internal class HolsterSetupInput : MonoBehaviour
	{
		private readonly List<InputActionMap> disabledMaps = new List<InputActionMap>();

		private HolsterSetupUI window;

		private PlayerControllerB player;

		private CursorLockMode cursorLock;

		private bool cursorVisible;

		private bool moveDisabled;

		private bool lookDisabled;

		private bool specialMenu;

		private bool quickMenu;

		private bool movementEnabled;

		private bool isOpen;

		private void Update()
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			if (isOpen)
			{
				GameNetworkManager instance = GameNetworkManager.Instance;
				if ((Object)(object)window == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)player == (Object)null || (Object)(object)instance.localPlayerController != (Object)(object)player || !player.isPlayerControlled || player.isPlayerDead)
				{
					Close();
				}
				else if (Keyboard.current != null && (((ButtonControl)Keyboard.current.f10Key).wasPressedThisFrame || ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame))
				{
					window.ExitClicked();
				}
			}
			else
			{
				if (Keyboard.current == null || !((ButtonControl)Keyboard.current.f10Key).wasPressedThisFrame || !PositionConfig.IsLoaded)
				{
					return;
				}
				GameNetworkManager instance2 = GameNetworkManager.Instance;
				if ((Object)(object)instance2 == (Object)null || (Object)(object)instance2.localPlayerController == (Object)null)
				{
					return;
				}
				player = instance2.localPlayerController;
				if (!player.isPlayerControlled || player.isPlayerDead || player.quickMenuManager.isMenuOpen || player.inTerminalMenu || player.isTypingChat || player.inSpecialMenu)
				{
					return;
				}
				window = Object.Instantiate<GameObject>(Plugin.HUDPrefab).GetComponent<HolsterSetupUI>();
				isOpen = true;
				cursorLock = Cursor.lockState;
				cursorVisible = Cursor.visible;
				moveDisabled = player.disableMoveInput;
				lookDisabled = player.disableLookInput;
				specialMenu = player.inSpecialMenu;
				quickMenu = player.quickMenuManager.isMenuOpen;
				MovementActions movement = player.playerActions.Movement;
				movementEnabled = ((MovementActions)(ref movement)).Get().enabled;
				player.disableMoveInput = true;
				player.disableLookInput = true;
				player.inSpecialMenu = true;
				player.quickMenuManager.isMenuOpen = true;
				movement = player.playerActions.Movement;
				((MovementActions)(ref movement)).Disable();
				Enumerator<InputActionMap> enumerator = InputSystem.actions.actionMaps.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						InputActionMap current = enumerator.Current;
						if (current.enabled && current.name != "UI")
						{
							disabledMaps.Add(current);
							current.Disable();
						}
					}
				}
				finally
				{
					((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					Cursor.SetCursor(HUDManager.Instance.defaultCursorTex, Vector2.zero, (CursorMode)0);
				}
				window.Input = this;
				window.Open(player);
			}
		}

		internal void Close()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (!isOpen)
			{
				return;
			}
			isOpen = false;
			if ((Object)(object)window != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)window).gameObject);
			}
			foreach (InputActionMap disabledMap in disabledMaps)
			{
				disabledMap.Enable();
			}
			disabledMaps.Clear();
			if ((Object)(object)player != (Object)null)
			{
				if (movementEnabled)
				{
					MovementActions movement = player.playerActions.Movement;
					((MovementActions)(ref movement)).Enable();
				}
				player.disableMoveInput = moveDisabled;
				player.disableLookInput = lookDisabled;
				player.inSpecialMenu = specialMenu;
				if ((Object)(object)player.quickMenuManager != (Object)null)
				{
					player.quickMenuManager.isMenuOpen = quickMenu;
				}
			}
			Cursor.lockState = cursorLock;
			Cursor.visible = cursorVisible;
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				Cursor.SetCursor(HUDManager.Instance.defaultCursorTex, Vector2.zero, (CursorMode)0);
			}
		}

		private void OnDestroy()
		{
			Close();
		}
	}
	public class HolsterSetupUI : MonoBehaviour
	{
		private enum Confirmation
		{
			None,
			Export,
			Exit,
			Delete,
			DeleteJson
		}

		[SerializeField]
		private Transform itemList;

		[SerializeField]
		private Button itemButtonPrefab;

		[SerializeField]
		private TMP_InputField searchInput;

		[SerializeField]
		private TMP_Text copiedItemText;

		[SerializeField]
		private Color configuredItemColor;

		[SerializeField]
		private Color selectedItemColor;

		[SerializeField]
		private TMP_Dropdown boneDropdown;

		[SerializeField]
		private HolsterValueControl[] values;

		[SerializeField]
		private HolsterPreview preview;

		[SerializeField]
		private TMP_Text positionFileText;

		[SerializeField]
		private TMP_Text savedExportedText;

		[SerializeField]
		private Button exportButton;

		[SerializeField]
		private TMP_Dropdown jsonDropdown;

		[SerializeField]
		private Button jsonDeleteButton;

		[SerializeField]
		private Button exitButton;

		[SerializeField]
		private GameObject confirmationPanel;

		[SerializeField]
		private TMP_Text confirmationText;

		[SerializeField]
		private Button confirmButton;

		[SerializeField]
		private Button cancelButton;

		private readonly Dictionary<NamespacedKey, HolsteredItemPosition> edits = new Dictionary<NamespacedKey, HolsteredItemPosition>();

		private readonly Dictionary<NamespacedKey, TMP_Text> itemLabels = new Dictionary<NamespacedKey, TMP_Text>();

		private readonly Dictionary<NamespacedKey, Button> itemButtons = new Dictionary<NamespacedKey, Button>();

		private readonly Dictionary<NamespacedKey, Button> resetButtons = new Dictionary<NamespacedKey, Button>();

		private readonly Dictionary<NamespacedKey, Button> deleteButtons = new Dictionary<NamespacedKey, Button>();

		private readonly Dictionary<NamespacedKey, Button> copyButtons = new Dictionary<NamespacedKey, Button>();

		private readonly Dictionary<NamespacedKey, Button> pasteButtons = new Dictionary<NamespacedKey, Button>();

		private readonly List<string> jsonFiles = new List<string>();

		private DawnItemInfo? selectedItem;

		private HolsteredItemPosition selectedPosition = new HolsteredItemPosition();

		private HolsteredItemPosition copiedPosition = new HolsteredItemPosition();

		private bool hasCopiedPosition;

		private string jsonFileToEdit = string.Empty;

		private string jsonFileToDelete = string.Empty;

		private Confirmation confirmation;

		internal HolsterSetupInput Input;

		private void Awake()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			((UnityEvent<string>)(object)searchInput.onValueChanged).AddListener((UnityAction<string>)SearchChanged);
			((UnityEvent<int>)(object)boneDropdown.onValueChanged).AddListener((UnityAction<int>)BoneChanged);
			((UnityEvent<int>)(object)jsonDropdown.onValueChanged).AddListener((UnityAction<int>)JsonFileChanged);
			((UnityEvent)exportButton.onClick).AddListener(new UnityAction(ExportClicked));
			((UnityEvent)jsonDeleteButton.onClick).AddListener(new UnityAction(DeleteJsonClicked));
			((UnityEvent)exitButton.onClick).AddListener(new UnityAction(ExitClicked));
			((UnityEvent)confirmButton.onClick).AddListener(new UnityAction(ConfirmClicked));
			((UnityEvent)cancelButton.onClick).AddListener(new UnityAction(CancelClicked));
			HolsterValueControl[] array = values;
			foreach (HolsterValueControl holsterValueControl in array)
			{
				holsterValueControl.Changed = ValueChanged;
			}
		}

		internal void Open(PlayerControllerB player)
		{
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Expected O, but got Unknown
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Expected O, but got Unknown
			confirmationPanel.SetActive(false);
			((Component)itemButtonPrefab).gameObject.SetActive(false);
			searchInput.SetTextWithoutNotify(string.Empty);
			boneDropdown.ClearOptions();
			boneDropdown.AddOptions(Enum.GetNames(typeof(PlayerBone)).ToList());
			hasCopiedPosition = false;
			copiedItemText.text = "COPIED: NONE";
			ListJsonFiles();
			preview.Open(player);
			savedExportedText.text = "SAVED & EXPORTED";
			List<DawnItemInfo> list = ((Registry<DawnItemInfo>)(object)LethalContent.Items).Values.OrderBy<DawnItemInfo, string>((DawnItemInfo val2) => val2.Item.itemName, StringComparer.OrdinalIgnoreCase).ThenBy<DawnItemInfo, string>((DawnItemInfo val2) => ((object)((DawnBaseInfo<DawnItemInfo>)(object)val2).Key).ToString(), StringComparer.Ordinal).ToList();
			foreach (DawnItemInfo info in list)
			{
				Button val = Object.Instantiate<Button>(itemButtonPrefab, itemList);
				bool flag = PositionConfig.PositionFor(info.Item) != null;
				if (PositionConfig.IsDisabled(info.Item))
				{
					ColorBlock colors = ((Selectable)itemButtonPrefab).colors;
					ColorItemButton(val, ((ColorBlock)(ref colors)).disabledColor);
				}
				else if (flag)
				{
					ColorItemButton(val, configuredItemColor);
				}
				else
				{
					ColorItemButton(val, ((Selectable)itemButtonPrefab).targetGraphic.color);
				}
				TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(true);
				componentInChildren.text = info.Item.itemName;
				Button component = ((Component)((Component)val).transform.Find("ResetButton")).GetComponent<Button>();
				((Selectable)component).interactable = false;
				((UnityEvent)component.onClick).AddListener((UnityAction)delegate
				{
					ResetClicked(info);
				});
				Button component2 = ((Component)((Component)val).transform.Find("DeleteButton")).GetComponent<Button>();
				((Selectable)component2).interactable = flag || PositionConfig.EntryInFile(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, jsonFiles[jsonDropdown.value]);
				((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
				{
					DeleteClicked(info);
				});
				Button component3 = ((Component)((Component)val).transform.Find("CopyButton")).GetComponent<Button>();
				((Selectable)component3).interactable = flag;
				((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
				{
					CopyClicked(info);
				});
				Button component4 = ((Component)((Component)val).transform.Find("PasteButton")).GetComponent<Button>();
				((Selectable)component4).interactable = false;
				((UnityEvent)component4.onClick).AddListener((UnityAction)delegate
				{
					PasteClicked(info);
				});
				itemLabels.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, componentInChildren);
				itemButtons.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, val);
				resetButtons.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, component);
				deleteButtons.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, component2);
				copyButtons.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, component3);
				pasteButtons.Add(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, component4);
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					Select(info);
				});
				((Component)val).gameObject.SetActive(true);
			}
			if (list.Count > 0)
			{
				Select(list[0]);
			}
			else
			{
				savedExportedText.text = "NO ITEMS REGISTERED";
			}
		}

		private void CopyClicked(DawnItemInfo info)
		{
			Select(info);
			copiedPosition = new HolsteredItemPosition(selectedPosition);
			hasCopiedPosition = true;
			copiedItemText.text = "COPIED: " + info.Item.itemName;
			foreach (Button value in pasteButtons.Values)
			{
				((Selectable)value).interactable = true;
			}
		}

		private void PasteClicked(DawnItemInfo info)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if (hasCopiedPosition)
			{
				Select(info);
				selectedPosition.Bone = copiedPosition.Bone;
				selectedPosition.Position = copiedPosition.Position;
				selectedPosition.Rotation = copiedPosition.Rotation;
				selectedPosition.Scale = copiedPosition.Scale;
				edits[((DawnBaseInfo<DawnItemInfo>)(object)info).Key] = selectedPosition;
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], Color.Lerp(configuredItemColor, Color.white, 0.25f));
				itemLabels[((DawnBaseInfo<DawnItemInfo>)(object)info).Key].text = info.Item.itemName + " *";
				((Selectable)resetButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = true;
				((Selectable)deleteButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = true;
				((Selectable)copyButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = true;
				savedExportedText.text = "UNSAVED CHANGES";
				boneDropdown.SetValueWithoutNotify((int)selectedPosition.Bone);
				HolsterValueControl[] array = values;
				foreach (HolsterValueControl holsterValueControl in array)
				{
					Vector3 val = ((holsterValueControl.Kind != HolsterValueKind.Position) ? ((holsterValueControl.Kind != HolsterValueKind.Rotation) ? selectedPosition.Scale : selectedPosition.Rotation) : selectedPosition.Position);
					holsterValueControl.Show(((Vector3)(ref val))[holsterValueControl.Axis]);
				}
				preview.Place(selectedPosition);
			}
		}

		private void SearchChanged(string search)
		{
			foreach (KeyValuePair<NamespacedKey, Button> itemButton in itemButtons)
			{
				bool flag = itemLabels[itemButton.Key].text.Contains(search, StringComparison.OrdinalIgnoreCase);
				bool flag2 = ((object)itemButton.Key).ToString().Contains(search, StringComparison.OrdinalIgnoreCase);
				((Component)itemButton.Value).gameObject.SetActive(flag || flag2);
			}
		}

		private void Select(DawnItemInfo info)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			ColorBlock colors;
			if (selectedItem != null)
			{
				Button button = itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key];
				if (edits.ContainsKey(((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key))
				{
					ColorItemButton(button, configuredItemColor);
				}
				else if (PositionConfig.IsDisabled(selectedItem.Item))
				{
					colors = ((Selectable)itemButtonPrefab).colors;
					ColorItemButton(button, ((ColorBlock)(ref colors)).disabledColor);
				}
				else if (PositionConfig.PositionFor(selectedItem.Item) != null)
				{
					ColorItemButton(button, configuredItemColor);
				}
				else
				{
					ColorItemButton(button, ((Selectable)itemButtonPrefab).targetGraphic.color);
				}
			}
			selectedItem = info;
			if (edits.ContainsKey(((DawnBaseInfo<DawnItemInfo>)(object)info).Key))
			{
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], Color.Lerp(configuredItemColor, Color.white, 0.25f));
			}
			else if (PositionConfig.IsDisabled(info.Item))
			{
				Button button2 = itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key];
				colors = ((Selectable)itemButtonPrefab).colors;
				ColorItemButton(button2, Color.Lerp(((ColorBlock)(ref colors)).disabledColor, Color.white, 0.25f));
			}
			else if (PositionConfig.PositionFor(info.Item) != null)
			{
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], Color.Lerp(configuredItemColor, Color.white, 0.25f));
			}
			else
			{
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], selectedItemColor);
			}
			if (edits.TryGetValue(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, out HolsteredItemPosition value))
			{
				selectedPosition = new HolsteredItemPosition(value);
			}
			else
			{
				HolsteredItemPosition holsteredItemPosition = PositionConfig.PositionFor(info.Item);
				if (holsteredItemPosition == null)
				{
					selectedPosition = new HolsteredItemPosition
					{
						Bone = PlayerBone.Spine3
					};
				}
				else
				{
					selectedPosition = new HolsteredItemPosition(holsteredItemPosition);
				}
			}
			string text = PositionConfig.FileFor(info.Item);
			if (PositionConfig.IsDisabled(info.Item))
			{
				positionFileText.text = "DISABLED IN: " + text;
			}
			else if (text.Length == 0)
			{
				positionFileText.text = "LOADED FROM: NONE";
			}
			else
			{
				positionFileText.text = "LOADED FROM: " + text;
			}
			boneDropdown.SetValueWithoutNotify((int)selectedPosition.Bone);
			HolsterValueControl[] array = values;
			Vector3 val = default(Vector3);
			foreach (HolsterValueControl holsterValueControl in array)
			{
				if (holsterValueControl.Kind == HolsterValueKind.Position)
				{
					val = selectedPosition.Position;
				}
				else if (holsterValueControl.Kind == HolsterValueKind.Rotation)
				{
					val = selectedPosition.Rotation;
				}
				else
				{
					((Vector3)(ref val))..ctor(selectedPosition.Scale.x, selectedPosition.Scale.x, selectedPosition.Scale.x);
				}
				holsterValueControl.Show(((Vector3)(ref val))[holsterValueControl.Axis]);
			}
			preview.Select(info.Item, selectedPosition);
		}

		private static void ColorItemButton(Button button, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			((Selectable)button).targetGraphic.color = Color.white;
			ColorBlock colors = ((Selectable)button).colors;
			((ColorBlock)(ref colors)).normalColor = color;
			((ColorBlock)(ref colors)).highlightedColor = Color.Lerp(color, Color.white, 0.2f);
			((ColorBlock)(ref colors)).pressedColor = Color.Lerp(color, Color.black, 0.15f);
			((ColorBlock)(ref colors)).selectedColor = color;
			((ColorBlock)(ref colors)).disabledColor = color;
			((Selectable)button).colors = colors;
		}

		private void BoneChanged(int index)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (selectedItem != null)
			{
				selectedPosition.Bone = (PlayerBone)index;
				edits[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key] = selectedPosition;
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key], Color.Lerp(configuredItemColor, Color.white, 0.25f));
				itemLabels[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key].text = selectedItem.Item.itemName + " *";
				((Selectable)resetButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				((Selectable)deleteButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				((Selectable)copyButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				savedExportedText.text = "UNSAVED CHANGES";
				preview.Place(selectedPosition);
			}
		}

		private void ValueChanged(HolsterValueControl value, float number)
		{
			//IL_0017: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (selectedItem != null)
			{
				Vector3 val;
				if (value.Kind == HolsterValueKind.Position)
				{
					val = selectedPosition.Position;
					((Vector3)(ref val))[value.Axis] = number;
					selectedPosition.Position = val;
				}
				else if (value.Kind == HolsterValueKind.Rotation)
				{
					val = selectedPosition.Rotation;
					((Vector3)(ref val))[value.Axis] = number;
					selectedPosition.Rotation = val;
				}
				else
				{
					selectedPosition.Scale = Vector3.one * number;
				}
				edits[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key] = selectedPosition;
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key], Color.Lerp(configuredItemColor, Color.white, 0.25f));
				itemLabels[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key].text = selectedItem.Item.itemName + " *";
				((Selectable)resetButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				((Selectable)deleteButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				((Selectable)copyButtons[((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key]).interactable = true;
				savedExportedText.text = "UNSAVED CHANGES";
				preview.Place(selectedPosition);
			}
		}

		private void ResetClicked(DawnItemInfo info)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			if (!edits.Remove(((DawnBaseInfo<DawnItemInfo>)(object)info).Key))
			{
				return;
			}
			itemLabels[((DawnBaseInfo<DawnItemInfo>)(object)info).Key].text = info.Item.itemName;
			((Selectable)resetButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = false;
			((Selectable)deleteButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = PositionConfig.PositionFor(info.Item) != null || PositionConfig.EntryInFile(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, jsonFiles[jsonDropdown.value]);
			((Selectable)copyButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key]).interactable = PositionConfig.PositionFor(info.Item) != null;
			if (selectedItem != null && ((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key == ((DawnBaseInfo<DawnItemInfo>)(object)info).Key)
			{
				Select(info);
				if (edits.Count == 0)
				{
					savedExportedText.text = "SAVED & EXPORTED";
				}
				else
				{
					savedExportedText.text = "UNSAVED CHANGES";
				}
				return;
			}
			if (PositionConfig.IsDisabled(info.Item))
			{
				Button button = itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key];
				ColorBlock colors = ((Selectable)itemButtonPrefab).colors;
				ColorItemButton(button, ((ColorBlock)(ref colors)).disabledColor);
			}
			else if (PositionConfig.PositionFor(info.Item) != null)
			{
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], configuredItemColor);
			}
			else
			{
				ColorItemButton(itemButtons[((DawnBaseInfo<DawnItemInfo>)(object)info).Key], ((Selectable)itemButtonPrefab).targetGraphic.color);
			}
			if (edits.Count == 0)
			{
				savedExportedText.text = "SAVED & EXPORTED";
			}
			else
			{
				savedExportedText.text = "UNSAVED CHANGES";
			}
		}

		private void DeleteClicked(DawnItemInfo info)
		{
			if (confirmation == Confirmation.None)
			{
				Select(info);
				jsonFileToEdit = jsonFiles[jsonDropdown.value];
				confirmation = Confirmation.Delete;
				if (PositionConfig.EntryInFile(((DawnBaseInfo<DawnItemInfo>)(object)info).Key, jsonFileToEdit))
				{
					confirmationText.text = "Remove the custom entry for " + info.Item.itemName + "?\n" + jsonFileToEdit + "\n\nThe next available position will be used";
				}
				else
				{
					confirmationText.text = "Disable the holster position for " + info.Item.itemName + "?\n" + jsonFileToEdit;
				}
				confirmationPanel.SetActive(true);
			}
		}

		private void ExportClicked()
		{
			if (edits.Count == 0)
			{
				savedExportedText.text = "SAVED & EXPORTED";
				return;
			}
			jsonFileToEdit = jsonFiles[jsonDropdown.value];
			if (File.Exists(jsonFileToEdit))
			{
				confirmation = Confirmation.Export;
				confirmationText.text = "Update this file?\n" + jsonFileToEdit + "\n\nEdited entries with the same keys will be replaced";
				confirmationPanel.SetActive(true);
			}
			else
			{
				WriteJson();
			}
		}

		private void ListJsonFiles()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			Directory.CreateDirectory(PositionConfig.DirectoryPath);
			string[] files = Directory.GetFiles(PositionConfig.DirectoryPath, "*.json", SearchOption.TopDirectoryOnly);
			Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
			jsonFiles.Clear();
			if (File.Exists(PositionConfig.CustomFilePath))
			{
				jsonFiles.Add(PositionConfig.CustomFilePath);
			}
			string[] array = files;
			foreach (string text in array)
			{
				if (!string.Equals(text, PositionConfig.DefaultFilePath, StringComparison.OrdinalIgnoreCase) && !string.Equals(text, PositionConfig.CustomFilePath, StringComparison.OrdinalIgnoreCase))
				{
					jsonFiles.Add(text);
				}
			}
			List<string> list = new List<string>();
			foreach (string jsonFile in jsonFiles)
			{
				list.Add(Path.GetFileName(jsonFile));
			}
			jsonDropdown.ClearOptions();
			jsonDropdown.AddOptions(list);
			jsonDropdown.SetValueWithoutNotify(0);
			Vector2 sizeDelta = jsonDropdown.template.sizeDelta;
			sizeDelta.y = Mathf.Min((float)jsonFiles.Count * 28f + 8f, 160f);
			jsonDropdown.template.sizeDelta = sizeDelta;
			((Selectable)jsonDeleteButton).interactable = jsonFiles.Count > 0;
			JsonFileChanged(0);
		}

		private void JsonFileChanged(int index)
		{
			string path = jsonFiles[index];
			foreach (KeyValuePair<NamespacedKey, Button> itemButton in itemButtons)
			{
				DawnItemInfo val = ((Registry<DawnItemInfo>)(object)LethalContent.Items)[itemButton.Key.AsTyped<DawnItemInfo>()];
				bool flag = edits.ContainsKey(itemButton.Key);
				bool flag2 = PositionConfig.PositionFor(val.Item) != null;
				((Selectable)deleteButtons[itemButton.Key]).interactable = flag || flag2 || PositionConfig.EntryInFile(itemButton.Key, path);
			}
		}

		private void DeleteJsonClicked()
		{
			if (confirmation == Confirmation.None && jsonFiles.Count != 0)
			{
				jsonFileToDelete = jsonFiles[jsonDropdown.value];
				confirmation = Confirmation.DeleteJson;
				if (string.Equals(jsonFileToDelete, PositionConfig.CustomFilePath, StringComparison.OrdinalIgnoreCase))
				{
					confirmationText.text = "Clear every custom holster position from this file?\n" + jsonFileToDelete;
				}
				else
				{
					confirmationText.text = "Delete this custom holster position file?\n" + jsonFileToDelete;
				}
				confirmationPanel.SetActive(true);
			}
		}

		private void WriteJson()
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int count = edits.Count;
				PositionConfig.Save(edits, jsonFileToEdit);
				foreach (NamespacedKey key in edits.Keys)
				{
					DawnItemInfo val = ((Registry<DawnItemInfo>)(object)LethalContent.Items)[key.AsTyped<DawnItemInfo>()];
					bool flag = PositionConfig.PositionFor(val.Item) != null;
					bool flag2 = PositionConfig.IsDisabled(val.Item);
					itemLabels[key].text = val.Item.itemName;
					((Selectable)resetButtons[key]).interactable = false;
					((Selectable)deleteButtons[key]).interactable = flag || PositionConfig.EntryInFile(key, jsonFileToEdit);
					((Selectable)copyButtons[key]).interactable = flag;
					ColorBlock colors;
					if (selectedItem == null)
					{
						if (flag2)
						{
							Button button = itemButtons[key];
							colors = ((Selectable)itemButtonPrefab).colors;
							ColorItemButton(button, ((ColorBlock)(ref colors)).disabledColor);
						}
						else if (flag)
						{
							ColorItemButton(itemButtons[key], configuredItemColor);
						}
						else
						{
							ColorItemButton(itemButtons[key], ((Selectable)itemButtonPrefab).targetGraphic.color);
						}
					}
					else if (((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key != key)
					{
						if (flag2)
						{
							Button button2 = itemButtons[key];
							colors = ((Selectable)itemButtonPrefab).colors;
							ColorItemButton(button2, ((ColorBlock)(ref colors)).disabledColor);
						}
						else if (flag)
						{
							ColorItemButton(itemButtons[key], configuredItemColor);
						}
						else
						{
							ColorItemButton(itemButtons[key], ((Selectable)itemButtonPrefab).targetGraphic.color);
						}
					}
				}
				edits.Clear();
				if (selectedItem != null)
				{
					Select(selectedItem);
				}
				savedExportedText.text = "SAVED & EXPORTED";
				Log.Info($"Saved {count} holster positions to {jsonFileToEdit}");
			}
			catch (Exception arg)
			{
				savedExportedText.text = "EXPORT FAILED";
				Log.Error($"Setup HUD failed to save positions: {arg}");
			}
		}

		internal void ExitClicked()
		{
			if (confirmation == Confirmation.None)
			{
				if (edits.Count > 0)
				{
					confirmation = Confirmation.Exit;
					confirmationText.text = "Leave without saving your changes?";
					confirmationPanel.SetActive(true);
				}
				else
				{
					Input.Close();
				}
			}
		}

		private void ConfirmClicked()
		{
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			confirmationPanel.SetActive(false);
			Confirmation confirmation = this.confirmation;
			this.confirmation = Confirmation.None;
			switch (confirmation)
			{
			case Confirmation.Exit:
				Input.Close();
				return;
			case Confirmation.Export:
				WriteJson();
				return;
			case Confirmation.Delete:
				if (selectedItem != null)
				{
					DawnItemInfo val = selectedItem;
					bool flag;
					try
					{
						flag = PositionConfig.Delete(((DawnBaseInfo<DawnItemInfo>)(object)val).Key, jsonFileToEdit);
					}
					catch (Exception arg)
					{
						savedExportedText.text = "DELETE FAILED";
						Log.Error($"Setup HUD failed to delete a position: {arg}");
						return;
					}
					edits.Remove(((DawnBaseInfo<DawnItemInfo>)(object)val).Key);
					((Selectable)resetButtons[((DawnBaseInfo<DawnItemInfo>)(object)val).Key]).interactable = false;
					((Selectable)deleteButtons[((DawnBaseInfo<DawnItemInfo>)(object)val).Key]).interactable = PositionConfig.PositionFor(val.Item) != null || PositionConfig.EntryInFile(((DawnBaseInfo<DawnItemInfo>)(object)val).Key, jsonFileToEdit);
					((Selectable)copyButtons[((DawnBaseInfo<DawnItemInfo>)(object)val).Key]).interactable = PositionConfig.PositionFor(val.Item) != null;
					itemLabels[((DawnBaseInfo<DawnItemInfo>)(object)val).Key].text = val.Item.itemName;
					Select(val);
					if (edits.Count == 0)
					{
						savedExportedText.text = "SAVED & EXPORTED";
					}
					else
					{
						savedExportedText.text = "UNSAVED CHANGES";
					}
					HolsteredItemNetwork instance = HolsteredItemNetwork.Instance;
					if ((Object)(object)instance != (Object)null)
					{
						HolsterVisuals.Refresh(instance);
					}
					if (flag)
					{
						Log.Info("Removed custom entry for " + val.Item.itemName + " from " + jsonFileToEdit);
					}
					else
					{
						Log.Info("Disabled holster position for " + val.Item.itemName + " in " + jsonFileToEdit);
					}
					return;
				}
				break;
			}
			if (confirmation != Confirmation.DeleteJson)
			{
				return;
			}
			bool flag2 = string.Equals(jsonFileToDelete, PositionConfig.CustomFilePath, StringComparison.OrdinalIgnoreCase);
			try
			{
				if (flag2)
				{
					File.WriteAllText(jsonFileToDelete, "{}" + Environment.NewLine);
				}
				else
				{
					File.Delete(jsonFileToDelete);
				}
				PositionConfig.Load();
			}
			catch (Exception arg2)
			{
				savedExportedText.text = "DELETE FAILED";
				Log.Error($"Setup HUD failed to delete {Path.GetFileName(jsonFileToDelete)}: {arg2}");
				return;
			}
			string fileName = Path.GetFileName(jsonFileToDelete);
			foreach (KeyValuePair<NamespacedKey, Button> itemButton in itemButtons)
			{
				DawnItemInfo val2 = ((Registry<DawnItemInfo>)(object)LethalContent.Items)[itemButton.Key.AsTyped<DawnItemInfo>()];
				bool flag3 = edits.ContainsKey(itemButton.Key);
				bool flag4 = PositionConfig.PositionFor(val2.Item) != null;
				bool flag5 = PositionConfig.IsDisabled(val2.Item);
				((Selectable)resetButtons[itemButton.Key]).interactable = flag3;
				((Selectable)deleteButtons[itemButton.Key]).interactable = flag3 || flag4;
				((Selectable)copyButtons[itemButton.Key]).interactable = flag3 || flag4;
				if (selectedItem == null || ((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key != itemButton.Key)
				{
					if (flag3)
					{
						ColorItemButton(itemButton.Value, configuredItemColor);
					}
					else if (flag5)
					{
						Button value = itemButton.Value;
						ColorBlock colors = ((Selectable)itemButtonPrefab).colors;
						ColorItemButton(value, ((ColorBlock)(ref colors)).disabledColor);
					}
					else if (flag4)
					{
						ColorItemButton(itemButton.Value, configuredItemColor);
					}
					else
					{
						ColorItemButton(itemButton.Value, ((Selectable)itemButtonPrefab).targetGraphic.color);
					}
				}
			}
			if (selectedItem != null && !edits.ContainsKey(((DawnBaseInfo<DawnItemInfo>)(object)selectedItem).Key))
			{
				Select(selectedItem);
			}
			if (edits.Count == 0)
			{
				savedExportedText.text = "SAVED & EXPORTED";
			}
			else
			{
				savedExportedText.text = "UNSAVED CHANGES";
			}
			ListJsonFiles();
			HolsteredItemNetwork instance2 = HolsteredItemNetwork.Instance;
			if ((Object)(object)instance2 != (Object)null)
			{
				HolsterVisuals.Refresh(instance2);
			}
			if (flag2)
			{
				Log.Info("Cleared custom holster position file " + fileName);
			}
			else
			{
				Log.Info("Deleted custom holster position file " + fileName);
			}
		}

		private void CancelClicked()
		{
			confirmationPanel.SetActive(false);
			confirmation = Confirmation.None;
		}
	}
	public enum HolsterValueKind
	{
		Position,
		Rotation,
		Scale
	}
	public class HolsterValueControl : MonoBehaviour
	{
		[SerializeField]
		private HolsterValueKind kind;

		[SerializeField]
		private int axis;

		[SerializeField]
		private Slider slider;

		[SerializeField]
		private TMP_InputField input;

		internal Action<HolsterValueControl, float> Changed;

		internal HolsterValueKind Kind => kind;

		internal int Axis => axis;

		private void Awake()
		{
			((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)OnSliderChanged);
			((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)OnTextChanged);
		}

		internal void Show(float value)
		{
			value = Mathf.Round(value * 100f) * 0.01f;
			slider.SetValueWithoutNotify(value);
			input.SetTextWithoutNotify(value.ToString("0.##", CultureInfo.InvariantCulture));
		}

		private void OnSliderChanged(float value)
		{
			value = Mathf.Round(value * 100f) * 0.01f;
			slider.SetValueWithoutNotify(value);
			input.SetTextWithoutNotify(value.ToString("0.##", CultureInfo.InvariantCulture));
			Changed(this, value);
		}

		private void OnTextChanged(string text)
		{
			if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || float.IsNaN(result) || float.IsInfinity(result))
			{
				Show(slider.value);
				return;
			}
			result = Mathf.Round(Mathf.Clamp(result, slider.minValue, slider.maxValue) * 100f) * 0.01f;
			Show(result);
			Changed(this, result);
		}
	}
}
namespace HolsteredItemPositions.Patches
{
	internal static class EnemyAIPatches
	{
		[HarmonyPatch(typeof(EnemyAI), "EnableEnemyMesh")]
		[HarmonyPostfix]
		private static void EnableEnemyMeshPostfix(EnemyAI __instance)
		{
			MaskedPlayerEnemy val = (MaskedPlayerEnemy)(object)((__instance is MaskedPlayerEnemy) ? __instance : null);
			if (val != null)
			{
				HolsterVisuals.SetMaskedItemLayer(val, ((Component)val.rendererLOD0).gameObject.layer);
			}
		}
	}
	[HarmonyPatch(typeof(FlashlightItem))]
	internal static class FlashlightItemPatches
	{
		[HarmonyPatch("SwitchFlashlight")]
		[HarmonyPatch("PocketFlashlightClientRpc")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "ReservedFlashlightSlot" })]
		private static void FlashlightPostfix(FlashlightItem __instance)
		{
			HolsteredItemNetwork instance = HolsteredItemNetwork.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.itemsById.ContainsKey(((NetworkBehaviour)__instance).NetworkObjectId))
			{
				HolsterVisuals.Refresh(instance);
			}
		}
	}
	internal static class GameNetworkManagerPatches
	{
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManagerStartPostfix()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null))
			{
				singleton.OnServerStarted += ServerStarted;
			}
		}

		private static void ServerStarted()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			GameObject networkPrefab = Plugin.NetworkPrefab;
			if (!((Object)(object)singleton == (Object)null) && !((Object)(object)networkPrefab == (Object)null) && singleton.IsServer && !((Object)(object)HolsteredItemNetwork.Instance != (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(networkPrefab);
				Object.DontDestroyOnLoad((Object)(object)val);
				NetworkObject val2 = default(NetworkObject);
				if (!val.TryGetComponent<NetworkObject>(ref val2))
				{
					Log.Error("Network object failed to spawn");
					Object.Destroy((Object)(object)val);
				}
				else
				{
					val2.Spawn(false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	internal static class GrabbableObjectPatches
	{
		[HarmonyPatch("PocketItem")]
		[HarmonyPrefix]
		private static void PocketItemPrefix(GrabbableObject __instance)
		{
			HolsterVisuals.BeforePocket(__instance);
		}

		[HarmonyPatch("PocketItem")]
		[HarmonyPostfix]
		private static void PocketItemPostfix(GrabbableObject __instance)
		{
			HolsteredItemNetwork.Pocket(__instance);
			HolsterVisuals.RefreshItem(__instance);
		}

		[HarmonyPatch("EquipItem")]
		[HarmonyPostfix]
		private static void EquipItemPostfix(GrabbableObject __instance)
		{
			HolsterVisuals.RestoreItem(__instance);
			HolsteredItemNetwork.Remove(__instance, __instance.playerHeldBy);
		}

		[HarmonyPatch("DiscardItem")]
		[HarmonyPrefix]
		private static void DiscardItemPrefix(GrabbableObject __instance)
		{
			HolsterVisuals.RestoreItem(__instance);
			HolsteredItemNetwork.Remove(__instance, __instance.playerHeldBy);
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		private static void LateUpdatePostfix(GrabbableObject __instance)
		{
			if (((NetworkBehaviour)__instance).IsSpawned)
			{
				HolsterVisuals.RefreshItem(__instance);
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix()
		{
			HolsteredItemNetwork instance = HolsteredItemNetwork.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				HolsterVisuals.Refresh(instance);
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPrefix(GrabbableObject __instance)
		{
			HolsterVisuals.RestoreItem(__instance);
			HolsteredItemNetwork instance = HolsteredItemNetwork.Instance;
			if (!((Object)(object)instance == (Object)null) && ((NetworkBehaviour)instance).IsServer)
			{
				instance.RemoveOnServer(((NetworkBehaviour)__instance).NetworkObjectId);
			}
		}
	}
	internal static class HauntedMaskItemPatches
	{
		[HarmonyPatch(typeof(HauntedMaskItem), "CreateMimicClientRpc")]
		[HarmonyPostfix]
		private static void CreateMimicClientRpcPostfix(HauntedMaskItem __instance, ref NetworkObjectReference netObjectRef)
		{
			if (ConfigManager.ShowItemsOnMaskedEnemies.Value && !((Object)(object)__instance.previousPlayerHeldBy == (Object)null))
			{
				PlayerControllerB previousPlayerHeldBy = __instance.previousPlayerHeldBy;
				HolsterVisuals.MaskedPlayerAssignments[((NetworkObjectReference)(ref netObjectRef)).NetworkObjectId] = previousPlayerHeldBy;
				NetworkObject val = default(NetworkObject);
				MaskedPlayerEnemy enemy = default(MaskedPlayerEnemy);
				if (((NetworkObjectReference)(ref netObjectRef)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<MaskedPlayerEnemy>(ref enemy))
				{
					HolsterVisuals.ShowMaskedItems(enemy, previousPlayerHeldBy);
				}
			}
		}
	}
	internal static class HUDManagerPatches
	{
		[HarmonyPatch(typeof(HUDManager), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(HUDManager __instance)
		{
			HolsterSetupInput holsterSetupInput = default(HolsterSetupInput);
			if (!((Object)(object)Plugin.HUDPrefab == (Object)null) && !((Component)__instance).TryGetComponent<HolsterSetupInput>(ref holsterSetupInput))
			{
				((Component)__instance).gameObject.AddComponent<HolsterSetupInput>();
				Log.Debug("HolsterSetupInput component added to HUDManager.Start");
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal static class MaskedPlayerEnemyPatches
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(MaskedPlayerEnemy __instance)
		{
			if (ConfigManager.ShowItemsOnMaskedEnemies.Value)
			{
				PlayerControllerB player = __instance.mimickingPlayer;
				if (HolsterVisuals.MaskedPlayerAssignments.TryGetValue(((NetworkBehaviour)__instance).NetworkObjectId, out PlayerControllerB value))
				{
					player = value;
				}
				HolsterVisuals.ShowMaskedItems(__instance, player);
			}
		}

		[HarmonyPatch("SetSuit")]
		[HarmonyPostfix]
		private static void SetSuitPostfix(MaskedPlayerEnemy __instance)
		{
			if (ConfigManager.ShowItemsOnMaskedEnemies.Value)
			{
				HolsterVisuals.ShowMaskedItems(__instance, __instance.mimickingPlayer);
			}
		}

		[HarmonyPatch("CreateMimicClientRpc")]
		[HarmonyPostfix]
		private static void CreateMimicClientRpcPostfix(ref NetworkObjectReference netObjectRef, int playerKilled)
		{
			if (ConfigManager.ShowItemsOnMaskedEnemies.Value)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerKilled];
				HolsterVisuals.MaskedPlayerAssignments[((NetworkObjectReference)(ref netObjectRef)).NetworkObjectId] = val;
				NetworkObject val2 = default(NetworkObject);
				MaskedPlayerEnemy enemy = default(MaskedPlayerEnemy);
				if (((NetworkObjectReference)(ref netObjectRef)).TryGet(ref val2, (NetworkManager)null) && ((Component)val2).TryGetComponent<MaskedPlayerEnemy>(ref enemy))
				{
					HolsterVisuals.ShowMaskedItems(enemy, val);
				}
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPrefix(MaskedPlayerEnemy __instance)
		{
			HolsterVisuals.RemoveMaskedItems(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatches
	{
		[HarmonyPatch("KillPlayer")]
		[HarmonyPrefix]
		private static void KillPlayerPrefix(PlayerControllerB __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)__instance).IsOwner && !__instance.isPlayerDead && __instance.AllowPlayerDeath())
			{
				if (ConfigManager.ShowItemsOnMaskedEnemies.Value)
				{
					HolsterVisuals.RememberMaskedItems(__instance);
				}
				HolsteredItemNetwork instance = HolsteredItemNetwork.Instance;
				if (!((Object)(object)instance == (Object)null) && ((NetworkBehaviour)instance).IsSpawned)
				{
					instance.MaskedDeathRpc(((NetworkBehaviour)__instance).NetworkObjectId);
				}
			}
		}

		[HarmonyPatch("KillPlayerServerRpc")]
		[HarmonyPatch("KillPlayerClientRpc")]
		[HarmonyPrefix]
		private static void KillPlayerRpcPrefix(PlayerControllerB __instance)
		{
			if (ConfigManager.ShowItemsOnMaskedEnemies.Value)
			{
				HolsterVisuals.RememberMaskedItems(__instance);
			}
		}

		[HarmonyPatch("SetObjectAsNoLongerHeld")]
		[HarmonyPrefix]
		private static void SetObjectAsNoLongerHeldPrefix(PlayerControllerB __instance, GrabbableObject dropObject)
		{
			HolsterVisuals.RestoreItem(dropObject);
			HolsteredItemNetwork.Remove(dropObject, __instance);
		}

		[HarmonyPatch("DestroyItemInSlot")]
		[HarmonyPrefix]
		private static void DestroyItemInSlotPrefix(PlayerControllerB __instance, int itemSlot)
		{
			GrabbableObject val;
			if (itemSlot == 50)
			{
				val = __instance.ItemOnlySlot;
			}
			else
			{
				if (itemSlot < 0 || itemSlot >= __instance.ItemSlots.Length)
				{
					return;
				}
				val = __instance.ItemSlots[itemSlot];
			}