Decompiled source of Holster Hider v1.2.0

Mods/HolsterHider.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
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 BoneLib;
using BoneLib.BoneMenu;
using HolsterHider;
using HolsterHider.MonoBehaviours;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Holster Hider")]
[assembly: MelonInfo(typeof(HolsterHiderMod), "Holster Hider", "1.2.0", "Lakatrazz", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
namespace HolsterHider
{
	public class BodyConfig
	{
		private readonly HolsterConfig[] _holsterConfigs;

		public HolsterConfig[] HolsterConfigs => _holsterConfigs;

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


		public HolsterConfig HeadGroup => HolsterConfigs[0];

		public HolsterConfig RightShoulderGroup => HolsterConfigs[1];

		public HolsterConfig LeftShoulderGroup => HolsterConfigs[2];

		public HolsterConfig RightUnderarmGroup => HolsterConfigs[3];

		public HolsterConfig LeftUnderarmGroup => HolsterConfigs[4];

		public HolsterConfig BackGroup => HolsterConfigs[5];

		public HolsterConfig AmmoPouchGroup => HolsterConfigs[6];

		public HolsterConfig BodyLogGroup => HolsterConfigs[7];

		public BodyConfig()
		{
			_holsterConfigs = new HolsterConfig[8]
			{
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig(),
				new HolsterConfig()
			};
		}
	}
	public class BodyPreferences
	{
		public HolsterPreference[] _holsterPreferences;

		public HolsterPreference[] HolsterPreferences => _holsterPreferences;

		public BoolPreference ScalePreference { get; set; }

		public HolsterPreference HeadPreference => _holsterPreferences[0];

		public HolsterPreference RightShoulderPreference => _holsterPreferences[1];

		public HolsterPreference LeftShoulderPreference => _holsterPreferences[2];

		public HolsterPreference RightUnderarmPreference => _holsterPreferences[3];

		public HolsterPreference LeftUnderarmPreference => _holsterPreferences[4];

		public HolsterPreference BackPreference => _holsterPreferences[5];

		public HolsterPreference AmmoPouchPreference => _holsterPreferences[6];

		public HolsterPreference BodyLogPreference => _holsterPreferences[7];

		public void LoadPreferences(MelonPreferences_Category category)
		{
			ScalePreference = new BoolPreference(category, "Resize Holsters");
			_holsterPreferences = new HolsterPreference[8]
			{
				new HolsterPreference(category, "Head"),
				new HolsterPreference(category, "Right Shoulder"),
				new HolsterPreference(category, "Left Shoulder"),
				new HolsterPreference(category, "Right Underarm"),
				new HolsterPreference(category, "Left Underarm"),
				new HolsterPreference(category, "Back"),
				new HolsterPreference(category, "Ammo Pouch"),
				new HolsterPreference(category, "Body Log")
			};
		}

		public void LoadConfig(BodyConfig config)
		{
			ScalePreference.OnSetValue = delegate(bool value)
			{
				config.ScaleHolsters = value;
			};
			ScalePreference.UpdatePreferences();
			for (int i = 0; i < HolsterPreferences.Length; i++)
			{
				HolsterPreferences[i].config = config.HolsterConfigs[i];
				HolsterPreferences[i].UpdatePreferences();
			}
		}

		public void UpdatePreferences()
		{
			ScalePreference.UpdatePreferences();
			HolsterPreference[] holsterPreferences = HolsterPreferences;
			for (int i = 0; i < holsterPreferences.Length; i++)
			{
				holsterPreferences[i].UpdatePreferences();
			}
		}

		public void ResetPreferences()
		{
			ScalePreference.SetValue(value: true);
			HolsterPreference[] holsterPreferences = HolsterPreferences;
			for (int i = 0; i < holsterPreferences.Length; i++)
			{
				holsterPreferences[i].SetVisibility(HolsterVisibility.DEFAULT);
			}
			HolsterHiderMod.UpdateHolsters();
		}
	}
	public class BodyReferences
	{
		private readonly HolsterReference[] _holsterReferences;

		private RigManager _rigManager;

		public HolsterReference[] HolsterReferences => _holsterReferences;

		public HolsterReference HeadGroup => _holsterReferences[0];

		public HolsterReference RightShoulderGroup => _holsterReferences[1];

		public HolsterReference LeftShoulderGroup => _holsterReferences[2];

		public HolsterReference RightUnderarmGroup => _holsterReferences[3];

		public HolsterReference LeftUnderarmGroup => _holsterReferences[4];

		public HolsterReference BackGroup => _holsterReferences[5];

		public HolsterReference AmmoPouchGroup => _holsterReferences[6];

		public HolsterReference BodyLogGroup => _holsterReferences[7];

		public BodyReferences()
		{
			_holsterReferences = new HolsterReference[8]
			{
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference(),
				new HolsterReference()
			};
		}

		public void ApplyConfig(BodyConfig bodyConfig)
		{
			if (!((Object)(object)_rigManager == (Object)null))
			{
				float scale = 1f;
				if (bodyConfig.ScaleHolsters)
				{
					scale = _rigManager.avatar.height / 1.76f;
				}
				for (int i = 0; i < HolsterReferences.Length; i++)
				{
					HolsterReference obj = HolsterReferences[i];
					obj.SetScale(scale);
					obj.SetVisibility(bodyConfig.HolsterConfigs[i].Visibility);
				}
			}
		}

		public void CacheReferences(RigManager rigManager)
		{
			_rigManager = rigManager;
			Il2CppReferenceArray<SlotContainer> bodySlots = rigManager.inventory.bodySlots;
			CacheHolster(((Component)((Rig)rigManager.physicsRig).m_head).GetComponentInChildren<InventorySlotReceiver>(true), HeadGroup);
			CacheHolster(((Il2CppArrayBase<SlotContainer>)(object)bodySlots)[3], RightShoulderGroup);
			CacheHolster(((Il2CppArrayBase<SlotContainer>)(object)bodySlots)[2], LeftShoulderGroup);
			CacheHolster(((Il2CppArrayBase<SlotContainer>)(object)bodySlots)[5], RightUnderarmGroup);
			CacheHolster(((Il2CppArrayBase<SlotContainer>)(object)bodySlots)[0], LeftUnderarmGroup);
			CacheHolster(((Il2CppArrayBase<SlotContainer>)(object)bodySlots)[4], BackGroup);
			CacheAmmoPouch(((Component)rigManager).GetComponentInChildren<InventoryAmmoReceiver>(true), AmmoPouchGroup);
			CachePullCord(((Component)((Il2CppArrayBase<SlotContainer>)(object)rigManager.inventory.specialItems)[0]).GetComponentInChildren<PullCordDevice>(true), BodyLogGroup);
		}

		private static void CacheHolster(SlotContainer slotContainer, HolsterReference holster)
		{
			Transform transform = ((Component)slotContainer).transform;
			InventorySlotReceiver inventorySlotReceiver = slotContainer.inventorySlotReceiver;
			holster.CacheReferences(transform, Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)transform).GetComponentsInChildren<MeshRenderer>(true)), inventorySlotReceiver);
		}

		private static void CacheHolster(InventorySlotReceiver slotReceiver, HolsterReference holster)
		{
			Transform parent = ((Component)slotReceiver).transform.parent;
			holster.CacheReferences(parent, Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)parent).GetComponentsInChildren<MeshRenderer>(true)), slotReceiver);
		}

		private static void CacheAmmoPouch(InventoryAmmoReceiver ammoReceiver, HolsterReference holster)
		{
			Transform parent = ((Component)ammoReceiver).transform.parent;
			holster.CacheReferences(parent, Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)parent).GetComponentsInChildren<MeshRenderer>(true)), ammoReceiver);
		}

		private static void CachePullCord(PullCordDevice pullCord, HolsterReference holster)
		{
			Transform transform = ((Component)pullCord).transform;
			holster.CacheReferences(transform, Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)transform.Find("BodyLog")).GetComponentsInChildren<MeshRenderer>(true)));
		}
	}
	public class BoolPreference
	{
		public MelonPreferences_Entry<bool> Preference;

		public BoolElement Element;

		public string Identifier;

		public Action<bool> OnSetValue;

		public BoolPreference(MelonPreferences_Category category, string identifier)
		{
			Preference = category.CreateEntry<bool>(identifier, true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Identifier = identifier;
		}

		public void OnBoneMenuChange(bool value)
		{
			SetValue(value);
			HolsterHiderMod.UpdateHolsters();
		}

		public void SetValue(bool value)
		{
			Preference.Value = value;
			((MelonPreferences_Entry)Preference).Category.SaveToFile(false);
			UpdatePreferences();
		}

		public void UpdatePreferences()
		{
			bool value = Preference.Value;
			if (Element != null)
			{
				Element.Value = value;
			}
			OnSetValue?.Invoke(value);
		}
	}
	public static class EmbeddedResource
	{
		public static byte[] LoadBytesFromAssembly(Assembly assembly, string name)
		{
			if (!assembly.GetManifestResourceNames().Contains(name))
			{
				return null;
			}
			using Stream stream = assembly.GetManifestResourceStream(name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static Assembly LoadAssemblyFromAssembly(Assembly assembly, string name)
		{
			byte[] array = LoadBytesFromAssembly(assembly, name);
			if (array == null)
			{
				return null;
			}
			return Assembly.Load(array);
		}
	}
	public enum HolsterVisibility
	{
		DEFAULT,
		INVISIBLE,
		DISABLED
	}
	public class HolsterConfig
	{
		public HolsterVisibility Visibility;
	}
	public class HolsterPreference
	{
		public MelonPreferences_Entry<HolsterVisibility> preference;

		public EnumElement element;

		public string identifier;

		public HolsterConfig config;

		public HolsterPreference(MelonPreferences_Category category, string identifier)
		{
			preference = category.CreateEntry<HolsterVisibility>(identifier, HolsterVisibility.DEFAULT, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			this.identifier = identifier;
		}

		public void OnBoneMenuChange(Enum value)
		{
			HolsterVisibility visibility = (HolsterVisibility)(object)value;
			SetVisibility(visibility);
			HolsterHiderMod.UpdateHolsters();
		}

		public void SetVisibility(HolsterVisibility visibility)
		{
			preference.Value = visibility;
			((MelonPreferences_Entry)preference).Category.SaveToFile(false);
			UpdatePreferences();
		}

		public void UpdatePreferences()
		{
			HolsterVisibility value = preference.Value;
			if (element != null)
			{
				element.Value = value;
			}
			if (config != null)
			{
				config.Visibility = value;
			}
		}
	}
	public class HolsterReference
	{
		private Transform _root;

		private Vector3 _rootLocalScale;

		private MeshRenderer[] _renderers;

		private InventorySlotReceiver _slotReceiver;

		private bool _hasSlotReceiver;

		private InventoryAmmoReceiver _ammoReceiver;

		private bool _hasAmmoReceiver;

		public void CacheReferences(Transform root, MeshRenderer[] renderers, InventorySlotReceiver slotReceiver)
		{
			_hasSlotReceiver = true;
			_slotReceiver = slotReceiver;
			CacheReferences(root, renderers);
		}

		public void CacheReferences(Transform root, MeshRenderer[] renderers, InventoryAmmoReceiver ammoReceiver)
		{
			_hasAmmoReceiver = true;
			_ammoReceiver = ammoReceiver;
			CacheReferences(root, renderers);
		}

		public void CacheReferences(Transform root, MeshRenderer[] renderers)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			_root = root;
			_rootLocalScale = root.localScale;
			_renderers = renderers;
		}

		public void SetScale(float scale)
		{
			if (_hasSlotReceiver && HasWeapon())
			{
				ScaleWithoutItem(scale);
			}
			else
			{
				ScaleRoot(scale);
			}
			ScaleMags();
		}

		private bool HasWeapon()
		{
			WeaponSlot slottedWeapon = _slotReceiver._slottedWeapon;
			if ((Object)(object)slottedWeapon != (Object)null && (Object)(object)slottedWeapon.interactableHost != (Object)null)
			{
				return (Object)(object)((MarrowBehaviour)slottedWeapon.interactableHost).marrowEntity != (Object)null;
			}
			return false;
		}

		private void ScaleWithoutItem(float scale)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)((MarrowBehaviour)_slotReceiver._slottedWeapon.interactableHost).marrowEntity).transform;
			Transform parent = transform.parent;
			Vector3 localPosition = transform.localPosition;
			transform.parent = null;
			ScaleRoot(scale);
			transform.parent = parent;
			transform.localPosition = localPosition;
		}

		private void ScaleRoot(float scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_root.localScale = _rootLocalScale * scale;
		}

		private void ScaleMags()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasAmmoReceiver)
			{
				return;
			}
			Enumerator<Magazine> enumerator = _ammoReceiver._magazineArts.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Magazine current = enumerator.Current;
				if ((Object)(object)current == (Object)null)
				{
					continue;
				}
				InteractableHost interactableHost = current.interactableHost;
				if (!((Object)(object)interactableHost == (Object)null))
				{
					MarrowEntity marrowEntity = ((MarrowBehaviour)interactableHost).marrowEntity;
					if (!((Object)(object)marrowEntity == (Object)null))
					{
						((Component)marrowEntity).transform.localScale = marrowEntity._originalScale;
					}
				}
			}
		}

		public void SetVisibility(HolsterVisibility visibility)
		{
			switch (visibility)
			{
			case HolsterVisibility.INVISIBLE:
			{
				((Component)_root).gameObject.SetActive(true);
				MeshRenderer[] renderers = _renderers;
				for (int i = 0; i < renderers.Length; i++)
				{
					((Renderer)renderers[i]).enabled = false;
				}
				break;
			}
			case HolsterVisibility.DISABLED:
				((Component)_root).gameObject.SetActive(false);
				break;
			default:
			{
				((Component)_root).gameObject.SetActive(true);
				MeshRenderer[] renderers = _renderers;
				for (int i = 0; i < renderers.Length; i++)
				{
					((Renderer)renderers[i]).enabled = true;
				}
				break;
			}
			}
		}
	}
	public class HolsterHiderMod : MelonMod
	{
		public const string Version = "1.2.0";

		public static readonly BodyPreferences BodyPreferences = new BodyPreferences();

		public static readonly BodyConfig LocalBodyConfig = new BodyConfig();

		private static bool _preferencesSetup = false;

		public static Assembly HolsterHiderAssembly { get; private set; } = null;


		public static MelonPreferences_Category MelonCategory { get; private set; }

		public static Page MainPage { get; private set; }

		public static HolsterHiderRig LocalRig { get; private set; } = null;


		public static event Action OnHolstersChanged;

		public override void OnLateInitializeMelon()
		{
			HolsterHiderAssembly = ((MelonBase)this).MelonAssembly.Assembly;
			MelonCategory = MelonPreferences.CreateCategory("Holster Hider");
			BodyPreferences.LoadPreferences(MelonCategory);
			BodyPreferences.LoadConfig(LocalBodyConfig);
			SetupBoneMenu();
			_preferencesSetup = true;
			Hooking.OnLevelLoaded += OnLevelLoaded;
			CheckFusion();
		}

		private static void CheckFusion()
		{
			if (MelonBase.FindMelon("LabFusion", "Lakatrazz") != null)
			{
				EmbeddedResource.LoadAssemblyFromAssembly(HolsterHiderAssembly, "HolsterHider.resources.HolsterHiderModule.dll").GetType("HolsterHiderModule.ModuleLoader").GetMethod("LoadModule")
					.Invoke(null, null);
			}
		}

		public static void SetupBoneMenu()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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)
			MainPage = Page.Root.CreatePage("Holster Hider", new Color(1f, 0.75f, 0.79f), 0, true);
			BoolPreference scalePreference = BodyPreferences.ScalePreference;
			BoolElement element = MainPage.CreateBool("Resize Holsters", Color.cyan, scalePreference.Preference.Value, (Action<bool>)scalePreference.OnBoneMenuChange);
			BodyPreferences.ScalePreference.Element = element;
			HolsterPreference[] holsterPreferences = BodyPreferences.HolsterPreferences;
			foreach (HolsterPreference holsterPreference in holsterPreferences)
			{
				holsterPreference.element = MainPage.CreateEnum(holsterPreference.identifier, Color.green, (Enum)holsterPreference.preference.Value, (Action<Enum>)holsterPreference.OnBoneMenuChange);
			}
			MainPage.CreateFunction("Reset Settings", Color.green, (Action)ResetHolsters);
		}

		public override void OnPreferencesLoaded()
		{
			if (_preferencesSetup)
			{
				UpdatePreferences();
				UpdateHolsters();
			}
		}

		private static void UpdatePreferences()
		{
			BodyPreferences.UpdatePreferences();
		}

		public static void UpdateHolsters()
		{
			if (!((Object)(object)LocalRig == (Object)null))
			{
				LocalRig.ApplyConfig();
				Action onHolstersChanged = HolsterHiderMod.OnHolstersChanged;
				if (onHolstersChanged != null)
				{
					Extensions.InvokeActionSafe(onHolstersChanged);
				}
			}
		}

		private static void ResetHolsters()
		{
			BodyPreferences.ResetPreferences();
			UpdateHolsters();
		}

		public static void OnLevelLoaded(LevelInfo level)
		{
			LocalRig = ((Component)Player.RigManager).gameObject.AddComponent<HolsterHiderRig>();
			LocalRig.Config = LocalBodyConfig;
			UpdateHolsters();
		}
	}
}
namespace HolsterHider.MonoBehaviours
{
	[RegisterTypeInIl2Cpp]
	public class HolsterHiderRig : MonoBehaviour
	{
		private BodyConfig _config;

		private Action _onAvatarSwappedDelegate;

		[HideFromIl2Cpp]
		public RigManager RigManager { get; set; }

		[HideFromIl2Cpp]
		public BodyReferences References { get; set; }

		[HideFromIl2Cpp]
		public BodyConfig Config
		{
			get
			{
				return _config;
			}
			set
			{
				_config = value;
				ApplyConfig();
			}
		}

		private void Awake()
		{
			RigManager = ((Component)this).GetComponent<RigManager>();
			References = new BodyReferences();
			References.CacheReferences(RigManager);
		}

		private void OnEnable()
		{
			HookRig();
		}

		private void OnDisable()
		{
			UnhookRig();
		}

		private void HookRig()
		{
			_onAvatarSwappedDelegate = Action.op_Implicit((Action)OnAvatarSwapped);
			RigManager.onAvatarSwapped = ((Il2CppObjectBase)Delegate.Combine((Delegate)(object)_onAvatarSwappedDelegate, (Delegate)(object)RigManager.onAvatarSwapped)).Cast<Action>();
		}

		private void UnhookRig()
		{
			RigManager rigManager = RigManager;
			rigManager.onAvatarSwapped -= _onAvatarSwappedDelegate;
			_onAvatarSwappedDelegate = null;
		}

		private void OnAvatarSwapped()
		{
			ApplyConfig();
		}

		public void ApplyConfig()
		{
			if (Config != null)
			{
				References.ApplyConfig(Config);
			}
		}
	}
}