Decompiled source of MagPerception v1.3.3

Mods/MagPerception.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppTMPro;
using LabFusion.Network;
using LabFusion.Player;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using NEP.MagPerception;
using NEP.MagPerception.UI;
using Tomlet.Attributes;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTrademark("NotEnoughPhotons")]
[assembly: ComVisible(false)]
[assembly: MelonInfo(typeof(Main), "MagPerception", "1.3.3", "NotEnoughPhotons", "https://thunderstore.io/c/bonelab/p/NotEnoughPhotons/MagPerception/")]
[assembly: AssemblyTitle("MagPerception")]
[assembly: AssemblyProduct("MagPerception")]
[assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyInformationalVersion("1.3.3")]
[assembly: AssemblyCompany("NotEnoughPhotons")]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.3.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NEP.MagPerception
{
	public static class Hooks
	{
		[HarmonyPatch(typeof(Grip), "OnAttachedToHand")]
		public static class OnGripAttached
		{
			public static Dictionary<Hand, Magazine> HoldMagazines { get; } = new Dictionary<Hand, Magazine>();


			public static void Postfix(Hand hand, Grip __instance)
			{
				if ((Object)(object)hand == (Object)null || (Object)(object)__instance == (Object)null || !((Component)(object)hand).IsPartOfLocalPlayer())
				{
					return;
				}
				Gun componentInParent = ((Component)__instance).GetComponentInParent<Gun>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					if (!MagPerceptionManager.LastGunGrips.ContainsKey(componentInParent))
					{
						MagPerceptionManager.LastGunGrips.Add(componentInParent, new List<Grip>(1) { __instance });
					}
					else
					{
						List<Grip> list = MagPerceptionManager.LastGunGrips[componentInParent];
						list.Add(__instance);
						MagPerceptionManager.LastGunGrips[componentInParent] = list;
					}
					MagPerceptionManager.OnGunAttached(componentInParent);
					return;
				}
				Magazine componentInParent2 = ((Component)__instance).GetComponentInParent<Magazine>();
				if ((Object)(object)componentInParent2 != (Object)null && !((Object)(object)__instance != (Object)(object)componentInParent2.grip))
				{
					MagPerceptionManager.OnMagazineAttached(componentInParent2);
					if (!HoldMagazines.ContainsKey(hand))
					{
						HoldMagazines.Add(hand, componentInParent2);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Grip), "OnDetachedFromHand")]
		public static class OnGripDetached
		{
			public static void Postfix(Hand hand, Grip __instance)
			{
				if ((Object)(object)hand == (Object)null || (Object)(object)__instance == (Object)null || !((Component)(object)hand).IsPartOfLocalPlayer())
				{
					return;
				}
				Gun componentInParent = ((Component)__instance).GetComponentInParent<Gun>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					if (MagPerceptionManager.LastGunGrips.TryGetValue(componentInParent, out var value) && value != null && value.Count == 1)
					{
						MagPerceptionManager.LastGunGrips.Remove(componentInParent);
					}
					else if (MagPerceptionManager.LastGunGrips.ContainsKey(componentInParent))
					{
						List<Grip> list = MagPerceptionManager.LastGunGrips[componentInParent];
						list.Remove(__instance);
						MagPerceptionManager.LastGunGrips[componentInParent] = list;
					}
					MagPerceptionManager.OnGunDetached(componentInParent);
					return;
				}
				Magazine componentInParent2 = ((Component)__instance).GetComponentInParent<Magazine>();
				if ((Object)(object)componentInParent2 != (Object)null && !((Object)(object)__instance != (Object)(object)componentInParent2.grip))
				{
					if (OnGripAttached.HoldMagazines.ContainsKey(hand))
					{
						OnGripAttached.HoldMagazines.Remove(hand);
					}
					MagPerceptionManager.OnMagazineDetached(componentInParent2);
				}
			}
		}

		[HarmonyPatch(typeof(Gun), "EjectCartridge")]
		public static class OnGunEjectRound
		{
			public static void Postfix(Gun __instance)
			{
				MagPerceptionManager.OnGunEjectRound(__instance);
			}
		}

		[HarmonyPatch(typeof(Gun), "OnMagazineInserted")]
		public static class OnMagazineInserted
		{
			public static void Postfix(Gun __instance)
			{
				MagPerceptionManager.OnMagazineInserted(__instance);
			}
		}

		[HarmonyPatch(typeof(Gun), "OnMagazineRemoved")]
		public static class OnMagazineRemoved
		{
			public static void Postfix(Gun __instance)
			{
				MagPerceptionManager.OnMagazineEjected(__instance);
			}
		}

		[HarmonyPatch(typeof(InventorySlotReceiver), "InsertInSlot")]
		public static class OnHolsteredGun
		{
			public static void Postfix(InventorySlotReceiver __instance, InteractableHost host)
			{
				if (!((Object)(object)__instance == (Object)null) && ((Component)(object)__instance).IsPartOfLocalPlayer())
				{
					Gun val = ((host != null) ? ((Component)host).GetComponent<Gun>() : null);
					if (!((Object)(object)val == (Object)null))
					{
						MagPerceptionManager.OnGunHolstered(val);
					}
				}
			}
		}
	}
	public static class MagPerceptionManager
	{
		internal static readonly Dictionary<Gun, List<Grip>> LastGunGrips = new Dictionary<Gun, List<Grip>>();

		internal static Dictionary<object, MagazineUI> MagazineUIs { get; } = new Dictionary<object, MagazineUI>();


		public static List<Gun> LastGuns { get; } = new List<Gun>();


		public static List<Magazine> LastMags { get; } = new List<Magazine>();


		internal static GameObject UIHolder { get; private set; }

		internal static void Initialize()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			UIHolder = new GameObject("[MagPerception] - UI Holder");
		}

		internal static void Clear()
		{
			MagazineUIs.Clear();
			LastGuns?.Clear();
			LastMags?.Clear();
			LastGunGrips.Clear();
			UIHolder = null;
		}

		private static MagazineUI AddMagazineUI(object gunOrMag, Vector3 startPosition, bool addOffset = true)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (gunOrMag.GetType() != typeof(Magazine) && gunOrMag.GetType() != typeof(Gun))
			{
				return null;
			}
			if (MagazineUIs.ContainsKey(gunOrMag))
			{
				return GetMagazineUI(gunOrMag);
			}
			GameObject val = Object.Instantiate<GameObject>(((Il2CppObjectBase)Main.Resources.LoadAsset("MagazineLayer")).Cast<GameObject>(), UIHolder.transform);
			val.transform.SetParent(UIHolder.transform);
			Transform transform = val.transform;
			? localPosition;
			if (addOffset)
			{
				Vector3? val2 = Settings.Instance?.Offset;
				localPosition = ((??)(val2.HasValue ? new Vector3?(startPosition + val2.GetValueOrDefault()) : null)) ?? Vector3.zero;
			}
			else
			{
				localPosition = startPosition;
			}
			transform.localPosition = (Vector3)localPosition;
			MagazineUI magazineUI = val.AddComponent<MagazineUI>();
			magazineUI.AmmoCounterText = ((Component)val.transform.Find("AmmoCounter")).GetComponent<TextMeshProUGUI>();
			magazineUI.AmmoInventoryText = ((Component)val.transform.Find("AmmoInventory")).GetComponent<TextMeshProUGUI>();
			magazineUI.AmmoTypeText = ((Component)val.transform.Find("AmmoType")).GetComponent<TextMeshProUGUI>();
			magazineUI.Animator = val.GetComponent<Animator>();
			val.SetActive(false);
			MagazineUIs.Add(gunOrMag, magazineUI);
			return magazineUI;
		}

		private static MagazineUI GetMagazineUI(object gunOrMag)
		{
			if (!(gunOrMag is Magazine) && !(gunOrMag is Gun))
			{
				return null;
			}
			if (!MagazineUIs.ContainsKey(gunOrMag))
			{
				return null;
			}
			return MagazineUIs[gunOrMag];
		}

		internal static void ClearMagazineUIs()
		{
			foreach (KeyValuePair<object, MagazineUI> magazineUI in MagazineUIs)
			{
				if ((Object)(object)magazineUI.Value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)magazineUI.Value).gameObject);
				}
			}
			MagazineUIs.Clear();
		}

		internal static void OnMagazineAttached(Magazine magazine)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)magazine == (Object)null))
			{
				LastMags.Add(magazine);
				MagazineUI magazineUI = AddMagazineUI(magazine, magazine.insertPointTransform.position);
				if (!((Object)(object)magazineUI == (Object)null))
				{
					magazineUI.OnMagEvent();
					magazineUI.UpdateParent(magazine.insertPointTransform);
					magazineUI.DisplayMagInfo(magazine);
				}
			}
		}

		internal static void OnMagazineDetached(Magazine magazine)
		{
			if (LastMags.Contains(magazine))
			{
				MagazineUI magazineUI = GetMagazineUI(magazine);
				LastMags.Remove(magazine);
				magazineUI?.FadeOut();
			}
		}

		internal static void OnMagazineInserted(Gun gun)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Instance.ShowWithGun && LastGuns.Contains(gun))
			{
				MagazineUI magazineUI = AddMagazineUI(gun, gun.firePointTransform.position);
				if (!((Object)(object)magazineUI == (Object)null))
				{
					magazineUI.OnMagEvent();
					magazineUI.UpdateParent(gun.firePointTransform);
					magazineUI.DisplayGunInfo(gun);
				}
			}
		}

		internal static void OnMagazineEjected(Gun gun)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Instance.ShowWithGun && LastGuns.Contains(gun))
			{
				MagazineUI magazineUI = AddMagazineUI(gun, gun.firePointTransform.position);
				if (!((Object)(object)magazineUI == (Object)null))
				{
					magazineUI.OnMagEvent();
					magazineUI.UpdateParent(gun.firePointTransform);
					magazineUI.DisplayGunInfo(gun);
				}
			}
		}

		internal static void OnGunAttached(Gun gun)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Instance.ShowWithGun && !((Object)(object)gun == (Object)null) && !((Object)(object)((Component)gun).GetComponent<SpawnGun>() != (Object)null))
			{
				LastGuns.Add(gun);
				MagazineUI magazineUI = AddMagazineUI(gun, gun.firePointTransform.position);
				if (!((Object)(object)magazineUI == (Object)null))
				{
					magazineUI.OnMagEvent();
					magazineUI.UpdateParent(gun.firePointTransform);
					magazineUI.DisplayGunInfo(gun);
				}
			}
		}

		internal static void OnGunDetached(Gun gun)
		{
			if (Settings.Instance.ShowWithGun && (!LastGunGrips.TryGetValue(gun, out var value) || value.Count <= 0) && LastGuns.Contains(gun))
			{
				LastGuns.Remove(gun);
				GetMagazineUI(gun)?.FadeOut();
			}
		}

		internal static void OnGunEjectRound(Gun gun)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Instance.ShowWithGun && LastGuns.Contains(gun))
			{
				MagazineUI magazineUI = AddMagazineUI(gun, gun.firePointTransform.position);
				if (!((Object)(object)magazineUI == (Object)null))
				{
					magazineUI.OnMagEvent();
					magazineUI.UpdateParent(gun.firePointTransform);
					magazineUI.DisplayGunInfo(gun);
				}
			}
		}

		internal static void OnGunHolstered(Gun gun)
		{
			if (Settings.Instance.ShowWithGun && LastGuns.Contains(gun))
			{
				if (LastGunGrips.ContainsKey(gun))
				{
					LastGunGrips[gun] = new List<Grip>();
				}
				OnGunDetached(gun);
			}
		}
	}
	public static class BuildInfo
	{
		public const string Name = "MagPerception";

		public const string Author = "NotEnoughPhotons";

		public const string Company = "NotEnoughPhotons";

		public const string Version = "1.3.3";

		public const string DownloadLink = "https://thunderstore.io/c/bonelab/p/NotEnoughPhotons/MagPerception/";
	}
	public class Main : MelonMod
	{
		private readonly List<Hand> _holding = new List<Hand>();

		internal static Instance Logger { get; private set; }

		internal static AssetBundle Resources { get; private set; }

		internal static MelonPreferences_ReflectiveCategory PrefsCategory { get; private set; }

		public static bool IsBoneLibLoaded { get; internal set; }

		public override void OnInitializeMelon()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			Logger = new Instance("MagPerception");
			IsBoneLibLoaded = MelonBase.FindMelon("BoneLib", "The BONELAB Modding Community") != null;
			if (!IsBoneLibLoaded)
			{
				Logger.Error("BoneLib is required for this mod to work");
			}
			else
			{
				OnInitialize();
			}
		}

		private static void OnInitialize()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = (HelperMethods.IsAndroid() ? "mp_resources_quest.pack" : "mp_resources_pcvr.pack");
			Resources = HelperMethods.LoadEmbeddedAssetBundle(executingAssembly, "NEP.MagPerception.Resources." + text);
			if ((Object)(object)Resources == (Object)null)
			{
				throw new Exception("Resources file is missing/invalid!");
			}
			SetupPreferences();
			SetupBonemenu();
			Hooking.OnLevelLoaded += delegate
			{
				OnSceneWasLoaded();
			};
		}

		private static void SetupPreferences()
		{
			PrefsCategory = MelonPreferences.CreateCategory<Settings>("MagPerception", (string)null);
			DirectoryInfo directoryInfo = Directory.CreateDirectory(Path.Combine(Directory.CreateDirectory(Path.Combine(MelonEnvironment.UserDataDirectory, "Not Enough Photons")).FullName, "MagPerception"));
			PrefsCategory.SetFilePath(Path.Combine(directoryInfo.FullName, "MagPerception.cfg"), true, true);
			PrefsCategory.SaveToFile(false);
			Settings.Instance = PrefsCategory.GetValue<Settings>();
		}

		private static void SetupBonemenu()
		{
			//IL_0010: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: 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_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Not Enough Photons", Color.white, 0, true).CreatePage("MagPerception", Color.white, 0, true);
			Page val2 = obj.CreatePage("Offset", Color.white, 0, true);
			Page val3 = obj.CreatePage("Text Color", Color.red, 0, true);
			Page val4 = obj.CreatePage("Helper", Color.cyan, 0, true);
			obj.CreateFloat("Text Opacity", Color.white, Settings.Instance.TextOpacity, 0.05f, 0.05f, 1f, (Action<float>)delegate(float value)
			{
				Settings.Instance.TextOpacity = value;
			});
			obj.CreateFloat("Scale", Color.white, Settings.Instance.InfoScale, 0.25f, 0.25f, 1.5f, (Action<float>)delegate(float value)
			{
				Settings.Instance.InfoScale = value;
			});
			obj.CreateEnum("Show Type", Color.white, (Enum)Settings.Instance.ShowType, (Action<Enum>)delegate(Enum showType)
			{
				Settings.Instance.ShowType = (UIShowType)(object)showType;
			});
			obj.CreateFloat("Time Until Hidden", Color.white, Settings.Instance.TimeUntilHidden, 0.5f, 0f, 10f, (Action<float>)delegate(float value)
			{
				Settings.Instance.TimeUntilHidden = value;
			});
			obj.CreateBool("Show With Gun", Color.white, Settings.Instance.ShowWithGun, (Action<bool>)delegate(bool value)
			{
				Settings.Instance.ShowWithGun = value;
			});
			val2.CreateFloat("X", Color.red, Settings.Instance.Offset.x, 0.025f, -1f, 1f, (Action<float>)delegate(float value)
			{
				Settings.Instance.ChangeXYZOffset(Settings.OffsetValue.X, value);
			});
			val2.CreateFloat("Y", Color.green, Settings.Instance.Offset.y, 0.025f, -1f, 1f, (Action<float>)delegate(float value)
			{
				Settings.Instance.ChangeXYZOffset(Settings.OffsetValue.Y, value);
			});
			val2.CreateFloat("Z", Color.blue, Settings.Instance.Offset.z, 0.025f, -1f, 1f, (Action<float>)delegate(float value)
			{
				Settings.Instance.ChangeXYZOffset(Settings.OffsetValue.Z, value);
			});
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Color32.op_Implicit(Settings.Instance.TextColor), ref num, ref num2, ref num3);
			FunctionElement preview = val3.CreateFunction("This is a preview", Color32.op_Implicit(Settings.Instance.TextColor), (Action)null);
			val3.CreateFloat("Hue", Color.red, num, 0.05f, 0f, 1f, (Action<float>)delegate(float val)
			{
				Settings.Instance.ChangeHSV(Settings.HSVValue.H, val);
			});
			val3.CreateFloat("Saturation", Color.green, num2, 0.05f, 0f, 1f, (Action<float>)delegate(float val)
			{
				Settings.Instance.ChangeHSV(Settings.HSVValue.S, val);
			});
			val3.CreateFloat("Value", Color.blue, num3, 0.05f, 0f, 1f, (Action<float>)delegate(float val)
			{
				Settings.Instance.ChangeHSV(Settings.HSVValue.V, val);
			});
			Settings instance = Settings.Instance;
			instance.OnColorChanged = (Action)Delegate.Combine(instance.OnColorChanged, (Action)delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				((Element)preview).ElementColor = Color32.op_Implicit(Settings.Instance.TextColor);
			});
			val4.CreateFunction("Clear all MagazineUI", Color.red, (Action)delegate
			{
				MagPerceptionManager.ClearMagazineUIs();
			});
		}

		public static void OnSceneWasLoaded()
		{
			if (IsBoneLibLoaded)
			{
				MagPerceptionManager.Clear();
				MagPerceptionManager.Initialize();
			}
		}

		internal static Object GetObjectFromResources(string name)
		{
			return ((IEnumerable<Object>)Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)Resources.LoadAllAssets())).FirstOrDefault((Func<Object, bool>)((Object asset) => asset.name == name));
		}

		private void MagUpdate(Hand hand)
		{
			if (!Hooks.OnGripAttached.HoldMagazines.ContainsKey(hand))
			{
				return;
			}
			Magazine val = Hooks.OnGripAttached.HoldMagazines[hand];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (KeyValuePair<object, MagazineUI> magazineUI in MagPerceptionManager.MagazineUIs)
			{
				if (magazineUI.Key == val)
				{
					MagazineUI value = magazineUI.Value;
					if ((Object)(object)hand != (Object)null && IsPressed(hand) && (Object)(object)val != (Object)null && (Object)(object)value != (Object)null && (value == null || !value.IsShown))
					{
						MagPerceptionManager.OnMagazineAttached(val);
					}
				}
			}
		}

		private bool IsPressed(Hand hand)
		{
			if ((Object)(object)hand.Controller == (Object)null)
			{
				return false;
			}
			if (!hand.Controller.GetMenuButtonDown())
			{
				_holding.Remove(hand);
			}
			else if (!_holding.Contains(hand))
			{
				_holding.Add(hand);
				return true;
			}
			return false;
		}

		public override void OnUpdate()
		{
			((MelonBase)this).OnUpdate();
			if (!IsBoneLibLoaded)
			{
				return;
			}
			foreach (KeyValuePair<object, MagazineUI> magazineUI in MagPerceptionManager.MagazineUIs)
			{
				MagazineUI value = magazineUI.Value;
				if (!((Object)(object)value == (Object)null))
				{
					if (value.fadeOut && value.IsShown)
					{
						value.FadeOut();
					}
					else if (!value.IsShown)
					{
						value.fadeOut = false;
					}
				}
			}
			if (Player.HandsExist)
			{
				MagUpdate(Player.LeftHand);
				MagUpdate(Player.RightHand);
			}
		}
	}
	public static class Fusion
	{
		public static bool HasFusion => MelonBase.FindMelon("LabFusion", "Lakatrazz") != null;

		public static bool IsConnected
		{
			get
			{
				if (HasFusion)
				{
					return Internal_IsConnected();
				}
				return false;
			}
		}

		private static bool Internal_IsConnected()
		{
			return NetworkInfo.HasServer;
		}

		private static bool Internal_IsPartOfLocalPlayer(this Component comp)
		{
			RigManager rigManager = (LocalPlayer.GetNetworkPlayer() ?? throw new NullReferenceException("Player is not connected to a Fusion lobby!")).RigRefs.RigManager;
			Transform root = comp.transform.root;
			RigManager val = default(RigManager);
			if (!RigManager.Cache.TryGet(((Component)root).gameObject, ref val))
			{
				throw new NullReferenceException("Fusion rig reference could not be found!");
			}
			if (((Il2CppObjectBase)rigManager).Pointer == ((Il2CppObjectBase)val).Pointer)
			{
				return true;
			}
			return false;
		}

		public static bool IsPartOfLocalPlayer(this Component comp)
		{
			if (IsConnected)
			{
				return comp.Internal_IsPartOfLocalPlayer();
			}
			return true;
		}
	}
	public class Settings
	{
		public enum OffsetValue
		{
			X,
			Y,
			Z
		}

		public enum HSVValue
		{
			H,
			S,
			V
		}

		[TomlNonSerialized]
		public Action OnColorChanged;

		[TomlNonSerialized]
		public static Settings Instance { get; internal set; }

		[TomlProperty("InfoScale")]
		private float _infoScale { get; set; } = 0.75f;


		[TomlNonSerialized]
		public float InfoScale
		{
			get
			{
				return _infoScale;
			}
			set
			{
				_infoScale = value;
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		[TomlProperty("Offset")]
		private Vector3 _offset { get; set; } = new Vector3(0.075f, 0f, 0f);


		[TomlNonSerialized]
		public Vector3 Offset
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _offset;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				_offset = value;
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		[TomlProperty("TimeUntilHidden")]
		private float _timeUntilHidden { get; set; } = 3f;


		[TomlNonSerialized]
		public float TimeUntilHidden
		{
			get
			{
				return _timeUntilHidden;
			}
			set
			{
				_timeUntilHidden = value;
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		[TomlProperty("ShowType")]
		private UIShowType _showType { get; set; } = UIShowType.FadeShow;


		[TomlNonSerialized]
		public UIShowType ShowType
		{
			get
			{
				return _showType;
			}
			set
			{
				_showType = value;
				Main.PrefsCategory.SaveToFile(false);
				List<Gun> lastGuns = MagPerceptionManager.LastGuns;
				if (lastGuns == null || lastGuns.Count <= 0)
				{
					List<Magazine> lastMags = MagPerceptionManager.LastMags;
					if (lastMags == null || lastMags.Count <= 0)
					{
						return;
					}
				}
				List<MagazineUI> UIs = new List<MagazineUI>();
				MagPerceptionManager.LastGuns.ForEach(delegate(Gun x)
				{
					if ((Object)(object)x != (Object)null && MagPerceptionManager.MagazineUIs.ContainsKey(x))
					{
						UIs.Add(MagPerceptionManager.MagazineUIs[x]);
					}
				});
				MagPerceptionManager.LastMags.ForEach(delegate(Magazine x)
				{
					if ((Object)(object)x != (Object)null && MagPerceptionManager.MagazineUIs.ContainsKey(x))
					{
						UIs.Add(MagPerceptionManager.MagazineUIs[x]);
					}
				});
				UIs.ForEach(delegate(MagazineUI x)
				{
					x.OnMagEvent();
				});
			}
		}

		[TomlProperty("ShowWithGun")]
		private bool _showWithGun { get; set; } = true;


		[TomlNonSerialized]
		public bool ShowWithGun
		{
			get
			{
				return _showWithGun;
			}
			set
			{
				_showWithGun = value;
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		[TomlProperty("TextOpacity")]
		private float _textOpacity { get; set; } = 0.5f;


		[TomlNonSerialized]
		public float TextOpacity
		{
			get
			{
				return _textOpacity;
			}
			set
			{
				_textOpacity = value;
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		[TomlNonSerialized]
		public Color32 TextColor
		{
			get
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				Color color = ColorTranslator.FromHtml(TextColorHEX);
				return new Color32(color.R, color.G, color.B, color.A);
			}
			set
			{
				//IL_0018: 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_003c: Unknown result type (might be due to invalid IL or missing references)
				TextColorHEX = $"#{value.r:X2}{value.g:X2}{value.b:X2}";
			}
		}

		[TomlProperty("TextColor")]
		private string _textColorHEX { get; set; } = "#FFFFFF";


		[TomlNonSerialized]
		public string TextColorHEX
		{
			get
			{
				return _textColorHEX;
			}
			set
			{
				_textColorHEX = value;
				OnColorChanged?.Invoke();
				Main.PrefsCategory.SaveToFile(false);
			}
		}

		public void ChangeHSV(HSVValue hsvValue, float value)
		{
			//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_0038: 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)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Color32.op_Implicit(TextColor), ref num, ref num2, ref num3);
			switch (hsvValue)
			{
			case HSVValue.H:
				num = value;
				break;
			case HSVValue.V:
				num3 = value;
				break;
			case HSVValue.S:
				num2 = value;
				break;
			}
			TextColor = Color32.op_Implicit(Color.HSVToRGB(num, num2, num3));
		}

		public void ChangeXYZOffset(OffsetValue xyz, float value)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector3 offset = Offset;
			switch (xyz)
			{
			case OffsetValue.X:
				offset.x = value;
				break;
			case OffsetValue.Y:
				offset.y = value;
				break;
			case OffsetValue.Z:
				offset.z = value;
				break;
			}
			Offset = offset;
		}
	}
}
namespace NEP.MagPerception.UI
{
	[RegisterTypeInIl2Cpp]
	public class MagazineUI : MonoBehaviour
	{
		private float timeSinceLastEvent;

		internal bool fadeOut;

		private float fadeOutTime;

		private const float fadeOutDuration = 0.25f;

		private Quaternion lastRotation;

		public TextMeshProUGUI AmmoCounterText { get; internal set; }

		public TextMeshProUGUI AmmoInventoryText { get; internal set; }

		public TextMeshProUGUI AmmoTypeText { get; internal set; }

		public Animator Animator { get; internal set; }

		public DisplayInfo DisplayInfo { get; private set; }

		public bool IsShown
		{
			get
			{
				if ((Object)(object)((Component)this).gameObject != (Object)null)
				{
					return ((Component)this).gameObject.active;
				}
				return false;
			}
		}

		public MagazineUI(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			Animator = ((Component)this).GetComponent<Animator>();
		}

		private void FixedUpdate()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_006e: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = new Vector3(-1f, 1f, 1f) * Settings.Instance.InfoScale;
			((Component)this).transform.LookAt(Player.Head);
			((Component)this).transform.localPosition = Vector3.Lerp(((Component)this).transform.localPosition, Vector3.zero + Settings.Instance.Offset, 8f * Time.fixedDeltaTime);
			((Component)this).transform.rotation = Quaternion.Slerp(lastRotation, ((Component)this).transform.rotation, 8f * Time.fixedDeltaTime);
			if ((Object)(object)AmmoCounterText != (Object)null)
			{
				((TMP_Text)AmmoCounterText).faceColor = Settings.Instance.TextColor;
				((TMP_Text)AmmoCounterText).alpha = Settings.Instance.TextOpacity;
			}
			if ((Object)(object)AmmoTypeText != (Object)null)
			{
				((TMP_Text)AmmoTypeText).faceColor = Settings.Instance.TextColor;
				((TMP_Text)AmmoTypeText).alpha = Settings.Instance.TextOpacity;
			}
			if ((Object)(object)AmmoInventoryText != (Object)null)
			{
				((TMP_Text)AmmoInventoryText).faceColor = Settings.Instance.TextColor;
				((TMP_Text)AmmoInventoryText).alpha = Settings.Instance.TextOpacity;
			}
			UIShowType showType = Settings.Instance.ShowType;
			if (DisplayInfo != null)
			{
				UpdateInfo(DisplayInfo);
			}
			switch (showType)
			{
			case UIShowType.FadeShow:
				timeSinceLastEvent += Time.deltaTime;
				if (timeSinceLastEvent > Settings.Instance.TimeUntilHidden)
				{
					timeSinceLastEvent = 0f;
					FadeOut();
				}
				break;
			case UIShowType.Hide:
				Hide();
				break;
			}
		}

		public void Show()
		{
			((Component)this).gameObject.SetActive(true);
		}

		public void Hide()
		{
			((Component)this).gameObject.SetActive(false);
		}

		public void OnMagEvent()
		{
			switch (Settings.Instance.ShowType)
			{
			case UIShowType.Always:
				if (!IsShown || fadeOut)
				{
					FadeIn();
				}
				break;
			case UIShowType.FadeShow:
				if (!IsShown || fadeOut)
				{
					FadeIn();
				}
				break;
			case UIShowType.Hide:
				Hide();
				break;
			}
		}

		public static string GetReserve(CartridgeData data)
		{
			if ((Object)(object)data == (Object)null || (Object)(object)AmmoInventory.Instance == (Object)null || AmmoInventory.Instance.GetGroupByCartridge(data) == null)
			{
				return "0";
			}
			if (MelonBase.FindMelon("InfiniteAmmo", "SoulWithMae") != null)
			{
				return "INFINITE";
			}
			return AmmoInventory.Instance.GetCartridgeCount(data).ToString();
		}

		public void DisplayGunInfo(Gun gun)
		{
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Invalid comparison between Unknown and I4
			DisplayInfo = new DisplayInfo(DisplayInfo.DisplayFor.GUN, gun);
			if ((Object)(object)gun == (Object)null)
			{
				return;
			}
			MagazineState magazineState = gun.MagazineState;
			string text;
			if (magazineState == null)
			{
				if ((Object)(object)gun.defaultMagazine != (Object)null && (Object)(object)gun.defaultCartridge != (Object)null)
				{
					text = (((Object)(object)gun.chamberedCartridge != (Object)null) ? $"+1/{gun.defaultMagazine.rounds}" : $"0/{gun.defaultMagazine.rounds}");
					((TMP_Text)AmmoCounterText).text = text;
					((TMP_Text)AmmoInventoryText).text = "RESERVE: " + GetReserve(gun.defaultCartridge);
					((TMP_Text)AmmoTypeText).text = ((!string.IsNullOrWhiteSpace(gun.defaultMagazine.platform)) ? gun.defaultMagazine.platform : "Unknown");
				}
				else
				{
					text = (((Object)(object)gun.chamberedCartridge != (Object)null) ? "+1/0" : "0/0");
					((TMP_Text)AmmoCounterText).text = text;
					((TMP_Text)AmmoInventoryText).text = "RESERVE: None";
					((TMP_Text)AmmoTypeText).text = "Unknown";
				}
				return;
			}
			bool num = (Object)(object)gun.chamberedCartridge != (Object)null;
			bool flag = num && magazineState.AmmoCount == magazineState.magazineData.rounds;
			int num2 = magazineState.AmmoCount;
			int rounds = magazineState.magazineData.rounds;
			string platform = magazineState.magazineData.platform;
			if (num && !flag && (int)gun.cartridgeState != 2)
			{
				num2++;
			}
			string reserve = GetReserve(magazineState.cartridgeData);
			text = (flag ? $"{num2}+1/{rounds}" : $"{num2}/{rounds}");
			((TMP_Text)AmmoCounterText).text = text;
			((TMP_Text)AmmoInventoryText).text = "RESERVE: " + reserve;
			((TMP_Text)AmmoTypeText).text = platform;
		}

		public void DisplayMagInfo(Magazine magazine)
		{
			DisplayInfo = new DisplayInfo(DisplayInfo.DisplayFor.MAG, magazine);
			MagazineState val = ((magazine != null) ? magazine.magazineState : null);
			if (val == null)
			{
				((TMP_Text)AmmoCounterText).text = "0/0";
				((TMP_Text)AmmoInventoryText).text = "RESERVE: None";
				((TMP_Text)AmmoTypeText).text = "Unknown";
				return;
			}
			int ammoCount = val.AmmoCount;
			int rounds = val.magazineData.rounds;
			string platform = val.magazineData.platform;
			string reserve = GetReserve(val.cartridgeData);
			((TMP_Text)AmmoCounterText).text = $"{ammoCount}/{rounds}";
			((TMP_Text)AmmoInventoryText).text = "RESERVE: " + reserve;
			((TMP_Text)AmmoTypeText).text = platform;
		}

		public void UpdateInfo(DisplayInfo info)
		{
			if (info == null || info.Object == null)
			{
				return;
			}
			if (info.Type == DisplayInfo.DisplayFor.GUN)
			{
				object @object = info.Object;
				Gun val = (Gun)((@object is Gun) ? @object : null);
				if (val != null)
				{
					DisplayGunInfo(val);
				}
			}
			else if (info.Type == DisplayInfo.DisplayFor.MAG)
			{
				object object2 = info.Object;
				Magazine val2 = (Magazine)((object2 is Magazine) ? object2 : null);
				if (val2 != null)
				{
					DisplayMagInfo(val2);
				}
			}
		}

		public void UpdateParent(Transform attachment)
		{
			((Component)this).transform.parent = attachment;
		}

		public void FadeIn()
		{
			timeSinceLastEvent = 0f;
			fadeOut = false;
			Show();
			Animator animator = Animator;
			if (animator != null)
			{
				animator.Play("mag_enter_01");
			}
		}

		public void FadeOut()
		{
			if (!fadeOut)
			{
				Animator animator = Animator;
				if (animator != null)
				{
					animator.SetTrigger("exit");
				}
				fadeOut = true;
			}
			else
			{
				fadeOutTime += Time.deltaTime;
				if (fadeOutTime > 0.25f)
				{
					fadeOutTime = 0f;
					Hide();
				}
			}
		}
	}
	public class DisplayInfo
	{
		public enum DisplayFor
		{
			GUN,
			MAG
		}

		public DisplayFor Type { get; }

		public object Object { get; }

		public DisplayInfo(DisplayFor type, object @object)
		{
			Type = type;
			if (!(@object is Magazine) && !(@object is Gun))
			{
				throw new Exception("Object must be of type Gun or Magazine!");
			}
			Object = @object;
		}
	}
	public enum UIShowType
	{
		Always,
		Hide,
		FadeShow
	}
}