Decompiled source of ReservedSlotPositionsForInventory v1.0.1

ReservedSlotPositionsForInventory.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Config;
using ReservedItemSlotCore.Data;
using ReservedSlotPositionsForInventory.Compatibility;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ReservedSlotPositionsForInventory")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1")]
[assembly: AssemblyProduct("ReservedSlotPositionsForInventory")]
[assembly: AssemblyTitle("ReservedSlotPositionsForInventory")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[module: UnverifiableCode]
[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 ReservedSlotPositionsForInventory
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("HQ_Team.ReservedSlotPositionsForInventory", "ReservedSlotPositionsForInventory", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "HQ_Team.ReservedSlotPositionsForInventory";

		private const string modName = "ReservedSlotPositionsForInventory";

		private const string modVersion = "1.0.1";

		private static Harmony _harmony;

		internal static ManualLogSource mls;

		internal static Plugin Instance;

		public static Dictionary<string, ConfigEntry<bool>> SlotToggles = new Dictionary<string, ConfigEntry<bool>>();

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			Instance = this;
			mls = Logger.CreateLogSource("HQ_Team.ReservedSlotPositionsForInventory");
			_harmony = new Harmony("HQ_Team.ReservedSlotPositionsForInventory");
			((Behaviour)this).enabled = true;
			CoreTMEBridge.Apply(_harmony);
			_harmony.PatchAll();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ReservedSlotPositionsForInventory";

		public const string PLUGIN_NAME = "ReservedSlotPositionsForInventory";

		public const string PLUGIN_VERSION = "0.0.1";
	}
}
namespace ReservedSlotPositionsForInventory.Patches
{
	public static class BoneDatabase
	{
		public static Dictionary<string, ReservedItemData> copiedData = new Dictionary<string, ReservedItemData>();

		public static HashSet<string> registeredItems = new HashSet<string>();
	}
	[HarmonyPatch(typeof(ReservedItemData))]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(new Type[]
	{
		typeof(string),
		typeof(PlayerBone),
		typeof(Vector3),
		typeof(Vector3)
	})]
	public static class BoneSnatcher
	{
		[HarmonyPostfix]
		private static void CaptureBones(ReservedItemData __instance, string itemName, PlayerBone holsteredParentBone, Vector3 holsteredPositionOffset, Vector3 holsteredRotationOffset)
		{
			BoneDatabase.copiedData[itemName] = __instance;
		}
	}
	[HarmonyPatch]
	public static class ReservedSlotPatch
	{
		private static readonly Dictionary<GameObject, int> previousLayers = new Dictionary<GameObject, int>();

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

		private const string logPrefix = "[RSPFI-Bones] ";

		private static bool IsLayerInLocalCameraMask(int layer)
		{
			Camera val = (StartOfRound.Instance?.localPlayerController)?.gameplayCamera;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			int cullingMask = val.cullingMask;
			return (cullingMask & (1 << layer)) != 0;
		}

		private static bool TryGetCoreItemData(GrabbableObject obj, out ReservedItemData data)
		{
			data = null;
			string key = (((Object)(object)obj.itemProperties != (Object)null) ? obj.itemProperties.itemName : "<null-name>");
			if (BoneDatabase.copiedData.TryGetValue(key, out data))
			{
				return true;
			}
			return false;
		}

		private static void ClearStaticDictionary(string fieldName)
		{
			if (typeof(ReservedItemSlotData).GetField(fieldName, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) is IDictionary dictionary)
			{
				dictionary.Clear();
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "PocketItem")]
		[HarmonyPostfix]
		public static void PocketItemPostfix(GrabbableObject __instance)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.playerHeldBy == (Object)null || !ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) || value.IsItemInReservedItemSlot(__instance) || !TryGetCoreItemData(__instance, out var data) || !data.showOnPlayerWhileHolstered || (int)data.holsteredParentBone == 0)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (((Object)val).name.Contains("ScanNode") || ((Component)val).gameObject.CompareTag("DoNotSet") || ((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					continue;
				}
				if (!previousLayers.ContainsKey(((Component)val).gameObject))
				{
					previousLayers[((Component)val).gameObject] = ((Component)val).gameObject.layer;
				}
				if (value.isLocalPlayer)
				{
					if (IsLayerInLocalCameraMask(((Component)val).gameObject.layer))
					{
						((Component)val).gameObject.layer = 23;
					}
				}
				else if (!IsLayerInLocalCameraMask(((Component)val).gameObject.layer))
				{
					((Component)val).gameObject.layer = 6;
				}
			}
			if (__instance.isPocketed)
			{
				value.boneMap.CreateBoneMap(((Component)value.playerController).transform, (List<string>)null);
				Transform bone = value.boneMap.GetBone(data.holsteredParentBone);
				if ((Object)(object)bone == (Object)null)
				{
					Debug.LogWarning((object)("[RSPFI-Bones] PocketItemPostfix: bone '" + ((object)(PlayerBone)(ref data.holsteredParentBone)).ToString() + "' not found for item '" + __instance.itemProperties.itemName + "'."));
				}
				else
				{
					__instance.parentObject = bone;
					((Component)__instance).transform.SetParent(bone, false);
					__instance.EnableItemMeshes(true);
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EquipItem")]
		[HarmonyPostfix]
		public static void EquipItemPostfix(GrabbableObject __instance)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.playerHeldBy == (Object)null || !ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) || value.IsItemInReservedItemSlot(__instance) || !TryGetCoreItemData(__instance, out var data) || !data.showOnPlayerWhileHolstered)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (previousLayers.TryGetValue(((Component)val).gameObject, out var value2))
				{
					((Component)val).gameObject.layer = value2;
					previousLayers.Remove(((Component)val).gameObject);
				}
			}
			__instance.parentObject = (value.isLocalPlayer ? __instance.playerHeldBy.localItemHolder : __instance.playerHeldBy.serverItemHolder);
		}

		[HarmonyPatch(typeof(GrabbableObject), "DiscardItem")]
		[HarmonyPostfix]
		public static void DiscardItemPostfix(GrabbableObject __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (previousLayers.TryGetValue(((Component)val).gameObject, out var value))
				{
					((Component)val).gameObject.layer = value;
					previousLayers.Remove(((Component)val).gameObject);
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void LateUpdatePostfix(GrabbableObject __instance)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.playerHeldBy == (Object)null || !ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) || value.IsItemInReservedItemSlot(__instance) || !TryGetCoreItemData(__instance, out var data) || !data.showOnPlayerWhileHolstered || (Object)(object)__instance == (Object)(object)value.currentlySelectedItem)
			{
				return;
			}
			if ((Object)(object)__instance.parentObject == (Object)null)
			{
				if (loggedItemNames.Add("no-parent:" + __instance.itemProperties.itemName))
				{
					Plugin.mls.LogDebug((object)("[RSPFI-Bones] LateUpdatePostfix: parentObject is null for '" + __instance.itemProperties.itemName + "' on player '" + __instance.playerHeldBy.playerUsername + "'."));
				}
			}
			else
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = transform.rotation * Quaternion.Euler(data.holsteredRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * data.holsteredPositionOffset;
			}
		}
	}
	[HarmonyPatch(typeof(SessionManager), "UnlockReservedItemSlot")]
	public static class ReservedSlotToggle
	{
		[HarmonyPrefix]
		private static bool Prefix(ReservedItemSlotData itemSlotData)
		{
			if (ConfigSettings.enablePurchasingItemSlots.Value)
			{
				return true;
			}
			if (itemSlotData == null)
			{
				return true;
			}
			string slotName = itemSlotData.slotName;
			if (ItemSlotConfig.slotToggles.TryGetValue(slotName, out var value) && value.Value)
			{
				return false;
			}
			return true;
		}
	}
	public static class SlotDatabase
	{
		public static Dictionary<string, HashSet<string>> slotToItems = new Dictionary<string, HashSet<string>>();
	}
	[HarmonyPatch(typeof(ReservedItemSlotData), "AddItemToReservedItemSlot", new Type[] { typeof(ReservedItemData) })]
	public static class ItemNameSnatcher
	{
		[HarmonyPrefix]
		public static void CaptureItems(ReservedItemSlotData __instance, ReservedItemData itemData)
		{
			if (itemData != null && !string.IsNullOrEmpty(itemData.itemName))
			{
				string slotName = __instance.slotName;
				if (!SlotDatabase.slotToItems.TryGetValue(slotName, out var value))
				{
					value = new HashSet<string>();
					SlotDatabase.slotToItems[slotName] = value;
				}
				if (value.Add(itemData.itemName))
				{
				}
				ItemSlotConfig.GetOrCreateConfig(slotName);
				string text = "Items used by " + slotName + " slot";
				ConfigEntry<string> val = default(ConfigEntry<string>);
				if (((BaseUnityPlugin)Plugin.Instance).Config.TryGetEntry<string>("ReservedSlots", text, ref val))
				{
					val.Value = string.Join(", ", SlotDatabase.slotToItems[slotName]);
				}
			}
		}
	}
	public static class ItemSlotConfig
	{
		public static Dictionary<string, ConfigEntry<bool>> slotToggles = new Dictionary<string, ConfigEntry<bool>>();

		public static ConfigEntry<bool> GetOrCreateConfig(string slotName)
		{
			if (slotToggles.TryGetValue(slotName, out var value))
			{
				return value;
			}
			string text = "Disable " + slotName + " reserved slot";
			string text2 = "Items used by " + slotName + " slot";
			ConfigEntry<bool> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("ReservedSlots", text, false, "Disable the ReservedItemSlotCore reserved slot '" + slotName + "'.");
			string text3 = "";
			if (SlotDatabase.slotToItems.TryGetValue(slotName, out var value2))
			{
				text3 = string.Join(", ", value2);
			}
			ConfigEntry<string> val2 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ReservedSlots", text2, text3, "Automatically generated list of items used by '" + slotName + "'. Does nothing if changed.");
			slotToggles[slotName] = val;
			return val;
		}
	}
	[HarmonyPatch(typeof(ReservedItemSlotData), "AddItemToReservedItemSlot")]
	public static class SlotSnatcher
	{
		[HarmonyPrefix]
		public static void Capture(ReservedItemSlotData __instance, ReservedItemData itemData)
		{
			if (itemData != null && !string.IsNullOrEmpty(itemData.itemName))
			{
				string slotName = __instance.slotName;
				if (!SlotDatabase.slotToItems.TryGetValue(slotName, out var value))
				{
					value = new HashSet<string>();
					SlotDatabase.slotToItems[slotName] = value;
				}
				value.Add(itemData.itemName);
				ItemSlotConfig.GetOrCreateConfig(slotName);
			}
		}
	}
}
namespace ReservedSlotPositionsForInventory.Compatibility
{
	internal static class CoreTMEBridge
	{
		public static void Apply(Harmony harmony)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("ReservedItemSlotCore.Compatibility.TooManyEmotes_Compat");
			if (!(type == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, "OnStartTMEEmote", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(type, "OnStopTMEEmote", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(CoreTMEBridge), "ForceInventoryItemsLayerOnStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(CoreTMEBridge), "ResetInventoryItemsLayerOnStop", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		internal static void ForceInventoryItemsLayerOnStart()
		{
			ReservedPlayerData localPlayerData = ReservedPlayerData.localPlayerData;
			if (localPlayerData == null)
			{
				return;
			}
			PlayerControllerB playerController = localPlayerData.playerController;
			if ((Object)(object)playerController == (Object)null)
			{
				return;
			}
			int layer = LayerMask.NameToLayer("Props");
			for (int i = 0; i < localPlayerData.reservedHotbarStartIndex; i++)
			{
				if (i == playerController.currentItemSlot)
				{
					continue;
				}
				GrabbableObject val = playerController.ItemSlots[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (!((Object)val2).name.Contains("ScanNode") && !((Component)val2).gameObject.CompareTag("DoNotSet") && !((Component)val2).gameObject.CompareTag("InteractTrigger"))
					{
						((Component)val2).gameObject.layer = layer;
					}
				}
			}
		}

		internal static void ResetInventoryItemsLayerOnStop()
		{
			ReservedPlayerData localPlayerData = ReservedPlayerData.localPlayerData;
			if (localPlayerData == null)
			{
				return;
			}
			PlayerControllerB playerController = localPlayerData.playerController;
			if ((Object)(object)playerController == (Object)null)
			{
				return;
			}
			int layer = LayerMask.NameToLayer("EnemiesNotRendered");
			for (int i = 0; i < localPlayerData.reservedHotbarStartIndex; i++)
			{
				if (i == playerController.currentItemSlot)
				{
					continue;
				}
				GrabbableObject val = playerController.ItemSlots[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (!((Object)val2).name.Contains("ScanNode") && !((Component)val2).gameObject.CompareTag("DoNotSet") && !((Component)val2).gameObject.CompareTag("InteractTrigger"))
					{
						((Component)val2).gameObject.layer = layer;
					}
				}
			}
		}
	}
}