Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ReservedSlotPositionsForInventory v1.0.6
ReservedSlotPositionsForInventory.dll
Decompiled a month agousing System; 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using HotbarPlus.Input; using Microsoft.CodeAnalysis; using ReservedItemSlotCore; using ReservedItemSlotCore.Config; using ReservedItemSlotCore.Data; using ReservedSlotPositionsForInventory.Cache; using ReservedSlotPositionsForInventory.Compatibility; using ReservedSlotPositionsForInventory.NetcodePatcher; using ReservedSlotPositionsForInventory.Networking; using ReservedSlotPositionsForInventory.Patches; using TooManyEmotes; using TooManyEmotes.Patches; using Unity.Collections; using Unity.Netcode; 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("1.0.6.0")] [assembly: AssemblyInformationalVersion("1.0.6")] [assembly: AssemblyProduct("ReservedSlotPositionsForInventory")] [assembly: AssemblyTitle("ReservedSlotPositionsForInventory")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 { internal static class ConfigManager { private static readonly Dictionary<string, SortedDictionary<string, string>> SlotToItems = new Dictionary<string, SortedDictionary<string, string>>(StringComparer.Ordinal); private static readonly Dictionary<string, ConfigEntry<bool>> SlotToggles = new Dictionary<string, ConfigEntry<bool>>(StringComparer.Ordinal); private static readonly Dictionary<string, ConfigEntry<string>> SlotItemLists = new Dictionary<string, ConfigEntry<string>>(StringComparer.Ordinal); internal static ConfigEntry<BoneVisibilityMode> BoneVisibilityModeConfig { get; private set; } internal static void Initialise(ConfigFile config) { BoneVisibilityModeConfig = config.Bind<BoneVisibilityMode>("General", "Visibility Mode", BoneVisibilityMode.FirstPickedUpMode, "Controls which item stays visible when multiple items share the same bone."); } internal static bool IsSlotDisabled(string slotName) { ConfigEntry<bool> value; return SlotToggles.TryGetValue(slotName, out value) && value.Value; } internal static void EnsureSlotConfig(string slotName) { if (!SlotToggles.ContainsKey(slotName)) { SlotToggles[slotName] = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("ReservedSlots", "Disable " + slotName + " reserved slot", false, "Disable the ReservedItemSlotCore reserved slot '" + slotName + "'. Will retain custom positions."); } if (!SlotItemLists.ContainsKey(slotName)) { SlotItemLists[slotName] = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("ReservedSlots", "Items used by " + slotName + " slot", SlotToItems.TryGetValue(slotName, out var value) ? string.Join(", ", value.Values) : string.Empty, "Automatically generated list of items used by '" + slotName + "'. Does nothing if changed and is purely informative."); } } internal static void Register(string slotName, ReservedItemData itemData) { if (!SlotToItems.TryGetValue(slotName, out var value)) { value = new SortedDictionary<string, string>(StringComparer.Ordinal); SlotToItems[slotName] = value; } string itemName = itemData.itemName; bool flag = HasBoneData(itemData); if (value.TryGetValue(itemName, out var value2) && !value2.EndsWith("[NO BONE DATA]", StringComparison.Ordinal) && !flag) { EnsureSlotConfig(slotName); return; } value[itemName] = (flag ? itemName : (itemName + " [NO BONE DATA]")); EnsureSlotConfig(slotName); SlotItemLists[slotName].Value = string.Join(", ", value.Values); } private static bool HasBoneData(ReservedItemData itemData) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 return itemData.showOnPlayerWhileHolstered && (int)itemData.holsteredParentBone > 0; } } internal enum BoneVisibilityMode { FirstPickedUpMode, LastItemHeldMode } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("HQ_Team.ReservedSlotPositionsForInventory", "ReservedSlotPositionsForInventory", "1.0.6")] public sealed class Plugin : BaseUnityPlugin { internal const string ModGuid = "HQ_Team.ReservedSlotPositionsForInventory"; private const string ModName = "ReservedSlotPositionsForInventory"; private const string ModVersion = "1.0.6"; private const string HasTooManyEmotes = "FlipMods.TooManyEmotes"; private const string HasHotbarPlus = "FlipMods.HotbarPlus"; private Harmony _harmony; internal static bool hasTooManyEmotes { get; private set; } internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown hasTooManyEmotes = Chainloader.PluginInfos.ContainsKey("FlipMods.TooManyEmotes"); Instance = this; Log = ((BaseUnityPlugin)this).Logger; ConfigManager.Initialise(((BaseUnityPlugin)this).Config); _harmony = new Harmony("HQ_Team.ReservedSlotPositionsForInventory"); _harmony.PatchAll(typeof(NetworkManagerPatches)); _harmony.PatchAll(typeof(SessionManagerPatches)); _harmony.PatchAll(typeof(ReservedItemSlotDataPatches)); _harmony.PatchAll(typeof(ReservedItemDataPatches)); _harmony.PatchAll(typeof(GrabbableObjectPatches)); _harmony.PatchAll(typeof(StartOfRoundPatches)); _harmony.PatchAll(typeof(FlashlightItemPatches)); _harmony.PatchAll(typeof(ReservedPlayerDataPatches)); _harmony.PatchAll(typeof(PlayerControllerBPatches)); if (Chainloader.PluginInfos.ContainsKey("FlipMods.TooManyEmotes")) { _harmony.PatchAll(typeof(TooManyEmotesCompat)); Log.LogInfo((object)"TooManyEmotes compatibility patch ran"); if (Chainloader.PluginInfos.ContainsKey("FlipMods.HotbarPlus")) { _harmony.PatchAll(typeof(HotbarPlusCompat)); Log.LogInfo((object)"HotbarPlus compatibility patch ran"); } } } } public static class PluginInfo { public const string PLUGIN_GUID = "ReservedSlotPositionsForInventory"; public const string PLUGIN_NAME = "ReservedSlotPositionsForInventory"; public const string PLUGIN_VERSION = "1.0.6"; } } namespace ReservedSlotPositionsForInventory.Patches { internal static class FlashlightItemPatches { [HarmonyPatch(typeof(FlashlightItem), "SwitchFlashlight")] [HarmonyPostfix] private static void SwitchFlashlightPostfix(FlashlightItem __instance, bool on) { if (on) { FlashlightPriorityCache.MarkToggledOn(__instance); } else { FlashlightPriorityCache.MarkToggledOff(__instance); } HolsterVisibilityCache.RefreshItem((GrabbableObject)(object)__instance); if (Plugin.hasTooManyEmotes) { TooManyEmotesCompat.RefreshItemDuringLocalEmote((GrabbableObject)(object)__instance); } } [HarmonyPatch(typeof(FlashlightItem), "PocketFlashlightClientRpc")] [HarmonyPostfix] private static void PocketFlashlightClientRpcPostfix(FlashlightItem __instance, bool stillUsingFlashlight) { if (stillUsingFlashlight) { FlashlightPriorityCache.MarkToggledOn(__instance); } else { FlashlightPriorityCache.MarkToggledOff(__instance); } HolsterVisibilityCache.RefreshItem((GrabbableObject)(object)__instance); if (Plugin.hasTooManyEmotes) { TooManyEmotesCompat.RefreshItemDuringLocalEmote((GrabbableObject)(object)__instance); } } [HarmonyPatch(typeof(FlashlightItem), "DiscardItem")] [HarmonyPostfix] private static void DiscardItemPostfix(FlashlightItem __instance) { FlashlightPriorityCache.MarkToggledOff(__instance); } [HarmonyPatch(typeof(FlashlightItem), "PocketItem")] [HarmonyPostfix] private static void PocketItemPostfix(FlashlightItem __instance) { if (((GrabbableObject)__instance).isPocketed && ((GrabbableObject)__instance).isBeingUsed && __instance.usingPlayerHelmetLight) { FlashlightPriorityCache.MarkToggledOn(__instance); } else { FlashlightPriorityCache.MarkToggledOff(__instance); } HolsterVisibilityCache.RefreshItem((GrabbableObject)(object)__instance); if (Plugin.hasTooManyEmotes) { TooManyEmotesCompat.RefreshItemDuringLocalEmote((GrabbableObject)(object)__instance); } } } internal static class GrabbableObjectPatches { internal const int HiddenFromLocalPlayerLayer = 23; private const int VisibleOnRemotePlayersLayer = 6; private static readonly HashSet<int> LoggedMissingParentItems = new HashSet<int>(); private static readonly HashSet<string> LoggedMissingBones = new HashSet<string>(); internal static bool IsLayerInLocalCameraMask(int layer) { Camera gameplayCamera = StartOfRound.Instance.localPlayerController.gameplayCamera; if ((Object)(object)gameplayCamera == (Object)null) { return false; } return (gameplayCamera.cullingMask & (1 << layer)) != 0; } internal static bool TryGetHolsterData(GrabbableObject item, PlayerControllerB playerController, out ReservedPlayerData playerData, out ReservedItemData itemData) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 playerData = null; itemData = null; if ((Object)(object)item == (Object)null || (Object)(object)playerController == (Object)null) { return false; } if (!ReservedPlayerData.allPlayerData.TryGetValue(playerController, out playerData)) { return false; } if (!IsVanillaInventoryOrUtilityItem(item, playerController, playerData)) { return false; } if (playerData.IsItemInReservedItemSlot(item)) { return false; } if (!BoneSlotData.TryGet(item, out itemData)) { return false; } return itemData.showOnPlayerWhileHolstered && (int)itemData.holsteredParentBone > 0; } internal static bool TryGetVisibilityHolsterData(GrabbableObject item, PlayerControllerB playerController, out ReservedItemData itemData) { itemData = null; if ((Object)(object)item == (Object)null || (Object)(object)playerController == (Object)null) { return false; } if (SessionManager.TryGetUnlockedItemData(item, ref itemData) && BoneSlotData.HasBoneData(itemData)) { return true; } return false; } private static void RestoreLayers(GrabbableObject item) { MeshRenderer[] renderers = RendererCache.GetRenderers(item); foreach (MeshRenderer val in renderers) { if (RendererCache.TryGetOriginalLayer(((Component)val).gameObject, out var layer)) { ((Component)val).gameObject.layer = layer; RendererCache.ForgetLayer(((Component)val).gameObject); } } } private static void SetItemVisible(GrabbableObject item, bool visible) { if ((Object)(object)item == (Object)null) { return; } item.EnableItemMeshes(visible); MeshRenderer[] renderers = RendererCache.GetRenderers(item); foreach (MeshRenderer val in renderers) { if ((Object)(object)val != (Object)null) { ((Renderer)val).enabled = visible; } } } internal static GrabbableObject GetEquippedItem(PlayerControllerB playerController) { if ((Object)(object)playerController == (Object)null) { return null; } if (playerController.currentItemSlot == 50) { return playerController.ItemOnlySlot; } int currentItemSlot = playerController.currentItemSlot; if (currentItemSlot < 0 || currentItemSlot >= playerController.ItemSlots.Length) { return null; } return playerController.ItemSlots[currentItemSlot]; } internal static bool IsVanillaInventoryOrUtilityItem(GrabbableObject item, PlayerControllerB playerController, ReservedPlayerData playerData) { if ((Object)(object)item == (Object)null || (Object)(object)playerController == (Object)null || playerData == null) { return false; } if ((Object)(object)playerController.ItemOnlySlot == (Object)(object)item) { return true; } int num = Mathf.Min(playerData.reservedHotbarStartIndex, playerController.ItemSlots.Length); for (int i = 0; i < num; i++) { if ((Object)(object)playerController.ItemSlots[i] == (Object)(object)item) { return true; } } return false; } internal static void Clear() { LoggedMissingParentItems.Clear(); LoggedMissingBones.Clear(); } [HarmonyPatch(typeof(GrabbableObject), "PocketItem")] [HarmonyPostfix] private static void PocketItemPostfix(GrabbableObject __instance) { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB playerHeldBy = __instance.playerHeldBy; if ((Object)(object)playerHeldBy == (Object)null) { return; } if (TryGetHolsterData(__instance, playerHeldBy, out var playerData, out var itemData)) { MeshRenderer[] renderers = RendererCache.GetRenderers(__instance); foreach (MeshRenderer val in renderers) { RendererCache.RememberLayer(((Component)val).gameObject); if (playerData.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) { playerData.boneMap.CreateBoneMap(((Component)playerData.playerController).transform, (List<string>)null); Transform bone = playerData.boneMap.GetBone(itemData.holsteredParentBone); if ((Object)(object)bone == (Object)null) { string item = $"{__instance.itemProperties.itemName}:{itemData.holsteredParentBone}"; if (LoggedMissingBones.Add(item)) { Plugin.Log.LogWarning((object)$"Failed to find bone '{itemData.holsteredParentBone}' for item '{__instance.itemProperties.itemName}'."); } } else { __instance.parentObject = bone; ((Component)__instance).transform.SetParent(bone, false); __instance.EnableItemMeshes(true); } } } if (__instance.isPocketed && TryGetVisibilityHolsterData(__instance, playerHeldBy, out var itemData2)) { HolsterOrderNetwork.EnsureFirstPickupOrder(__instance); HolsterVisibilityCache.RegisterPocketedItem(playerHeldBy, itemData2.holsteredParentBone, __instance); } } [HarmonyPatch(typeof(GrabbableObject), "EquipItem")] [HarmonyPatch(typeof(StunGrenadeItem), "EquipItem")] [HarmonyPostfix] private static void EquipItemPostfix(GrabbableObject __instance) { HolsterVisibilityCache.RemoveItem(__instance); if (!TryGetHolsterData(__instance, __instance.playerHeldBy, out var playerData, out var _)) { SetItemVisible(__instance, visible: true); return; } RestoreLayers(__instance); Transform val = (__instance.parentObject = (playerData.isLocalPlayer ? __instance.playerHeldBy.localItemHolder : __instance.playerHeldBy.serverItemHolder)); if ((Object)(object)val != (Object)null) { ((Component)__instance).transform.SetParent(val, false); } SetItemVisible(__instance, visible: true); } [HarmonyPatch(typeof(GrabbableObject), "DiscardItem")] [HarmonyPostfix] private static void DiscardItemPostfix(GrabbableObject __instance) { if (!((Object)(object)__instance == (Object)null)) { RestoreLayers(__instance); HolsterOrderNetwork.NotifyDroppedItem(__instance); HolsterVisibilityCache.RemoveItemAndForgetPriority(__instance); } } [HarmonyPatch(typeof(GrabbableObject), "LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix(GrabbableObject __instance) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0103: 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_011b: 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_012b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.playerHeldBy == (Object)null || !__instance.isHeld || !TryGetHolsterData(__instance, __instance.playerHeldBy, out var playerData, out var itemData) || (Object)(object)__instance == (Object)(object)GetEquippedItem(playerData.playerController)) { return; } if ((Object)(object)__instance.parentObject == (Object)null) { int instanceID = ((Object)__instance).GetInstanceID(); if (LoggedMissingParentItems.Add(instanceID)) { Plugin.Log.LogDebug((object)("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(itemData.holsteredRotationOffset); ((Component)__instance).transform.position = transform.position + transform.rotation * itemData.holsteredPositionOffset; } } } [HarmonyPatch] internal static class NetworkManagerPatches { [HarmonyPatch(typeof(NetworkManager), "Initialize")] [HarmonyPostfix] private static void InitializePostfix() { HolsterOrderNetwork.RegisterMessages(); } [HarmonyPatch(typeof(GameNetworkManager), "SetInstanceValuesBackToDefault")] [HarmonyPostfix] private static void ResetPostfix() { HolsterOrderNetwork.UnregisterMessages(); } } internal class PlayerControllerBPatches { [HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")] [HarmonyPrefix] [HarmonyAfter(new string[] { "ReservedItemSlotCore" })] private static void BeginGrabObjectPrefix(PlayerControllerB __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.currentItemSlot == 50 && ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value) && value.isGrabbingReservedItem) { value.previousHotbarIndex = 50; } } [HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")] [HarmonyPrefix] [HarmonyAfter(new string[] { "ReservedItemSlotCore" })] private static void GrabObjectClientRpcPrefix(bool grabValidated, PlayerControllerB __instance) { if (grabValidated && !((Object)(object)__instance == (Object)null) && __instance.currentItemSlot == 50 && ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value) && value.isGrabbingReservedItem) { value.previousHotbarIndex = 50; } } } internal static class BoneSlotData { private static readonly Dictionary<string, ReservedItemData> CopiedData = new Dictionary<string, ReservedItemData>(StringComparer.Ordinal); internal static bool TryGet(GrabbableObject item, out ReservedItemData itemData) { itemData = null; string text = item?.itemProperties?.itemName; return text != null && CopiedData.TryGetValue(text, out itemData); } internal static bool TryGet(string itemName, out ReservedItemData itemData) { itemData = null; return !string.IsNullOrEmpty(itemName) && CopiedData.TryGetValue(itemName, out itemData); } internal static void Set(string itemName, ReservedItemData itemData) { if (string.IsNullOrEmpty(itemName) || itemData == null) { return; } bool flag = HasBoneData(itemData); if (!CopiedData.TryGetValue(itemName, out var value)) { CopiedData[itemName] = itemData; return; } bool flag2 = HasBoneData(value); if (!flag2 || flag) { if (!flag2 && flag) { CopiedData[itemName] = itemData; } else if (!(flag2 && flag)) { } } } internal static bool HasBoneData(ReservedItemData itemData) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 return itemData != null && itemData.showOnPlayerWhileHolstered && (int)itemData.holsteredParentBone > 0; } } [HarmonyPatch(typeof(ReservedItemData))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(new Type[] { typeof(string), typeof(PlayerBone), typeof(Vector3), typeof(Vector3) })] internal static class ReservedItemDataPatches { [HarmonyPostfix] private static void Postfix(ReservedItemData __instance, string itemName) { BoneSlotData.Set(itemName, __instance); } } internal static class ReservedItemSlotDataPatches { [HarmonyPatch(typeof(ReservedItemSlotData), "AddItemToReservedItemSlot", new Type[] { typeof(ReservedItemData) })] [HarmonyPrefix] private static void Prefix(ReservedItemSlotData __instance, ReservedItemData itemData) { if (itemData != null && !string.IsNullOrEmpty(itemData.itemName)) { ConfigManager.Register(__instance.slotName, itemData); } } [HarmonyPatch(typeof(ReservedItemSlotData), "CreateReservedItemSlotData")] [HarmonyPostfix] private static void Postfix(ReservedItemSlotData __result) { if (__result != null) { ConfigManager.EnsureSlotConfig(__result.slotName); } } } internal static class ReservedPlayerDataPatches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void CurrentlySelectedItemGetterPostfix(ReservedPlayerData __instance, ref GrabbableObject __result) { if (__instance != null && !((Object)(object)__instance.playerController == (Object)null) && __instance.currentItemSlot == 50) { __result = __instance.playerController.ItemOnlySlot; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void PreviouslyHeldItemGetterPostfix(ReservedPlayerData __instance, ref GrabbableObject __result) { if (__instance != null && !((Object)(object)__instance.playerController == (Object)null) && __instance.previousHotbarIndex == 50) { __result = __instance.playerController.ItemOnlySlot; } } } internal static class SessionManagerPatches { [HarmonyPatch(typeof(SessionManager), "UnlockReservedItemSlot")] [HarmonyPrefix] private static bool Prefix(ReservedItemSlotData itemSlotData) { if (ConfigSettings.enablePurchasingItemSlots.Value || itemSlotData == null) { return true; } return !ConfigManager.IsSlotDisabled(itemSlotData.slotName); } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void TryGetUnlockedItemDataPostfix(GrabbableObject item, ref ReservedItemData itemData, ref bool __result) { if ((!__result || !BoneSlotData.HasBoneData(itemData)) && BoneSlotData.TryGet(item, out var itemData2) && BoneSlotData.HasBoneData(itemData2)) { itemData = itemData2; __result = true; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void TryGetUnlockedItemDataPostfix(string itemName, ref ReservedItemData itemData, ref bool __result) { if ((!__result || !BoneSlotData.HasBoneData(itemData)) && BoneSlotData.TryGet(itemName, out var itemData2) && BoneSlotData.HasBoneData(itemData2)) { itemData = itemData2; __result = true; } } } internal static class StartOfRoundPatches { [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] [HarmonyPostfix] private static void Postfix() { Stopwatch stopwatch = Stopwatch.StartNew(); Plugin.Log.LogInfo((object)"Starting cleanup."); GrabbableObjectPatches.Clear(); Plugin.Log.LogDebug((object)"GrabbableObjectPatches caches cleared"); RendererCache.Clear(); Plugin.Log.LogDebug((object)"Renderer cache cleared"); HolsterVisibilityCache.Clear(); Plugin.Log.LogDebug((object)"HolsterVisibility cache cleared"); HolsterOrderNetwork.UnregisterMessages(); Plugin.Log.LogDebug((object)"HolsterOrderNetwork cache cleared"); FlashlightPriorityCache.Clear(); Plugin.Log.LogDebug((object)"FlashlightPriority cache cleared"); stopwatch.Stop(); Plugin.Log.LogInfo((object)$"Cleanup complete in {stopwatch.Elapsed.TotalMilliseconds:F3} ms"); } } } namespace ReservedSlotPositionsForInventory.Networking { internal static class HolsterOrderNetwork { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnSetFirstPickupOrderServerRpc; public static HandleNamedMessageDelegate <1>__OnSetFirstPickupOrderClientRpc; public static HandleNamedMessageDelegate <2>__OnForgetFirstPickupOrderServerRpc; public static HandleNamedMessageDelegate <3>__OnForgetFirstPickupOrderClientRpc; } private static readonly string SetFirstPickupOrderServerRpcMessage = "HQ_Team.ReservedSlotPositionsForInventory.SetFirstPickupOrderServerRpc"; private static readonly string SetFirstPickupOrderClientRpcMessage = "HQ_Team.ReservedSlotPositionsForInventory.SetFirstPickupOrderClientRpc"; private static readonly string ForgetFirstPickupOrderServerRpcMessage = "HQ_Team.ReservedSlotPositionsForInventory.ForgetFirstPickupOrderServerRpc"; private static readonly string ForgetFirstPickupOrderClientRpcMessage = "HQ_Team.ReservedSlotPositionsForInventory.ForgetFirstPickupOrderClientRpc"; private static long _nextLocalOrder; private static bool _registered; internal static void RegisterMessages() { //IL_0042: 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_004d: Expected O, but got Unknown //IL_0069: 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_0074: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown if (!_registered && NetworkManager.Singleton.CustomMessagingManager != null) { CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager; string setFirstPickupOrderServerRpcMessage = SetFirstPickupOrderServerRpcMessage; object obj = <>O.<0>__OnSetFirstPickupOrderServerRpc; if (obj == null) { HandleNamedMessageDelegate val = OnSetFirstPickupOrderServerRpc; <>O.<0>__OnSetFirstPickupOrderServerRpc = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler(setFirstPickupOrderServerRpcMessage, (HandleNamedMessageDelegate)obj); string setFirstPickupOrderClientRpcMessage = SetFirstPickupOrderClientRpcMessage; object obj2 = <>O.<1>__OnSetFirstPickupOrderClientRpc; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnSetFirstPickupOrderClientRpc; <>O.<1>__OnSetFirstPickupOrderClientRpc = val2; obj2 = (object)val2; } customMessagingManager.RegisterNamedMessageHandler(setFirstPickupOrderClientRpcMessage, (HandleNamedMessageDelegate)obj2); string forgetFirstPickupOrderServerRpcMessage = ForgetFirstPickupOrderServerRpcMessage; object obj3 = <>O.<2>__OnForgetFirstPickupOrderServerRpc; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnForgetFirstPickupOrderServerRpc; <>O.<2>__OnForgetFirstPickupOrderServerRpc = val3; obj3 = (object)val3; } customMessagingManager.RegisterNamedMessageHandler(forgetFirstPickupOrderServerRpcMessage, (HandleNamedMessageDelegate)obj3); string forgetFirstPickupOrderClientRpcMessage = ForgetFirstPickupOrderClientRpcMessage; object obj4 = <>O.<3>__OnForgetFirstPickupOrderClientRpc; if (obj4 == null) { HandleNamedMessageDelegate val4 = OnForgetFirstPickupOrderClientRpc; <>O.<3>__OnForgetFirstPickupOrderClientRpc = val4; obj4 = (object)val4; } customMessagingManager.RegisterNamedMessageHandler(forgetFirstPickupOrderClientRpcMessage, (HandleNamedMessageDelegate)obj4); _registered = true; _nextLocalOrder = 0L; } } internal static void UnregisterMessages() { if (_registered && NetworkManager.Singleton.CustomMessagingManager != null) { CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager; customMessagingManager.UnregisterNamedMessageHandler(SetFirstPickupOrderServerRpcMessage); customMessagingManager.UnregisterNamedMessageHandler(SetFirstPickupOrderClientRpcMessage); customMessagingManager.UnregisterNamedMessageHandler(ForgetFirstPickupOrderServerRpcMessage); customMessagingManager.UnregisterNamedMessageHandler(ForgetFirstPickupOrderClientRpcMessage); _registered = false; _nextLocalOrder = 0L; } } internal static void EnsureFirstPickupOrder(GrabbableObject item) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (HolsterVisibilityCache.UsesSyncedFirstPickupOrdering && TryGetNetworkObjectReference(item, out var itemReference) && (ConfigManager.BoneVisibilityModeConfig.Value == BoneVisibilityMode.LastItemHeldMode || !HolsterVisibilityCache.HasSyncedFirstPickupOrder(((NetworkObjectReference)(ref itemReference)).NetworkObjectId))) { long order = _nextLocalOrder++; HolsterVisibilityCache.ApplySyncedFirstPickupOrder(((NetworkObjectReference)(ref itemReference)).NetworkObjectId, order); if (NetworkManager.Singleton.IsServer) { SendSetFirstPickupOrderClientRpc(itemReference, order); } else { SendSetFirstPickupOrderServerRpc(itemReference, order); } } } internal static void NotifyDroppedItem(GrabbableObject item) { //IL_0037: 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) if (TryGetNetworkObjectReference(item, out var itemReference)) { if (NetworkManager.Singleton.IsServer) { HolsterVisibilityCache.RemoveSyncedFirstPickupOrder(((NetworkObjectReference)(ref itemReference)).NetworkObjectId); SendForgetFirstPickupOrderClientRpc(itemReference); } else { SendForgetFirstPickupOrderServerRpc(itemReference); } } } private static void SendSetFirstPickupOrderServerRpc(NetworkObjectReference itemReference, long order) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteNetworkSerializable<NetworkObjectReference>(ref itemReference); ((FastBufferWriter)(ref val)).WriteValueSafe<long>(ref order, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(SetFirstPickupOrderServerRpcMessage, 0uL, val, (NetworkDelivery)2); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void SendSetFirstPickupOrderClientRpc(NetworkObjectReference itemReference, long order) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteNetworkSerializable<NetworkObjectReference>(ref itemReference); ((FastBufferWriter)(ref val)).WriteValueSafe<long>(ref order, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(SetFirstPickupOrderClientRpcMessage, val, (NetworkDelivery)2); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void SendForgetFirstPickupOrderServerRpc(NetworkObjectReference itemReference) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteNetworkSerializable<NetworkObjectReference>(ref itemReference); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(ForgetFirstPickupOrderServerRpcMessage, 0uL, val, (NetworkDelivery)2); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void SendForgetFirstPickupOrderClientRpc(NetworkObjectReference itemReference) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteNetworkSerializable<NetworkObjectReference>(ref itemReference); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(ForgetFirstPickupOrderClientRpcMessage, val, (NetworkDelivery)2); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private static void OnSetFirstPickupOrderServerRpc(ulong senderId, FastBufferReader reader) { //IL_0026: 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_0041: Unknown result type (might be due to invalid IL or missing references) if (!NetworkManager.Singleton.IsServer) { return; } try { NetworkObjectReference itemReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref itemReference); long order = default(long); ((FastBufferReader)(ref reader)).ReadValueSafe<long>(ref order, default(ForPrimitives)); HolsterVisibilityCache.ApplySyncedFirstPickupOrder(((NetworkObjectReference)(ref itemReference)).NetworkObjectId, order); SendSetFirstPickupOrderClientRpc(itemReference, order); } catch (Exception arg) { Plugin.Log.LogError((object)$"SetFirstPickupOrderServerRpc: {arg}"); } } private static void OnSetFirstPickupOrderClientRpc(ulong senderId, FastBufferReader reader) { //IL_001e: 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) if (senderId != 0) { return; } try { NetworkObjectReference val = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref val); long order = default(long); ((FastBufferReader)(ref reader)).ReadValueSafe<long>(ref order, default(ForPrimitives)); HolsterVisibilityCache.ApplySyncedFirstPickupOrder(((NetworkObjectReference)(ref val)).NetworkObjectId, order); } catch (Exception arg) { Plugin.Log.LogError((object)$"SetFirstPickupOrderClientRpc: {arg}"); } } private static void OnForgetFirstPickupOrderServerRpc(ulong senderId, FastBufferReader reader) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!NetworkManager.Singleton.IsServer) { return; } try { NetworkObjectReference itemReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref itemReference); HolsterVisibilityCache.RemoveSyncedFirstPickupOrder(((NetworkObjectReference)(ref itemReference)).NetworkObjectId); SendForgetFirstPickupOrderClientRpc(itemReference); } catch (Exception arg) { Plugin.Log.LogError((object)$"ForgetFirstPickupOrderServerRpc: {arg}"); } } private static void OnForgetFirstPickupOrderClientRpc(ulong senderId, FastBufferReader reader) { if (senderId != 0) { return; } try { NetworkObjectReference val = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref val); HolsterVisibilityCache.RemoveSyncedFirstPickupOrder(((NetworkObjectReference)(ref val)).NetworkObjectId); } catch (Exception arg) { Plugin.Log.LogError((object)$"ForgetFirstPickupOrderClientRpc: {arg}"); } } private static bool TryGetNetworkObjectReference(GrabbableObject item, out NetworkObjectReference itemReference) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) itemReference = default(NetworkObjectReference); if ((Object)(object)item == (Object)null || (Object)(object)((NetworkBehaviour)item).NetworkObject == (Object)null || !((NetworkBehaviour)item).NetworkObject.IsSpawned) { return false; } itemReference = NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject); return true; } } } namespace ReservedSlotPositionsForInventory.Compatibility { [HarmonyPatch(typeof(Keybinds), "OnPressItemSlotHotkeyAction")] internal static class HotbarPlusCompat { [HarmonyPrefix] private static bool Prefix() { EmoteControllerPlayer emoteControllerLocal = EmoteControllerPlayer.emoteControllerLocal; return (Object)(object)emoteControllerLocal == (Object)null || !((EmoteController)emoteControllerLocal).IsPerformingCustomEmote(); } } internal static class TooManyEmotesCompat { internal static bool IsLocalCustomEmoteActive { get; private set; } internal static void RefreshItemDuringLocalEmote(GrabbableObject item) { if (!IsLocalCustomEmoteActive || (Object)(object)item == (Object)null) { return; } ReservedPlayerData localPlayerData = ReservedPlayerData.localPlayerData; if (localPlayerData == null) { return; } PlayerControllerB playerController = localPlayerData.playerController; if ((Object)(object)playerController == (Object)null || (Object)(object)item.playerHeldBy != (Object)(object)playerController) { return; } int num = Mathf.Min(localPlayerData.reservedHotbarStartIndex, playerController.ItemSlots.Length); bool flag = false; for (int i = 0; i < num; i++) { if (!((Object)(object)playerController.ItemSlots[i] != (Object)(object)item)) { if (i == playerController.currentItemSlot) { return; } flag = true; break; } } if (!flag && (Object)(object)playerController.ItemOnlySlot == (Object)(object)item) { if (playerController.currentItemSlot == 50) { return; } flag = true; } if (!flag || !GrabbableObjectPatches.TryGetHolsterData(item, playerController, out var _, out var _)) { return; } MeshRenderer[] renderers = RendererCache.GetRenderers(item); foreach (MeshRenderer val in renderers) { ((Renderer)val).enabled = true; if (RendererCache.TryGetOriginalLayer(((Component)val).gameObject, out var layer) && !GrabbableObjectPatches.IsLayerInLocalCameraMask(((Component)val).gameObject.layer)) { ((Component)val).gameObject.layer = layer; } } } [HarmonyPatch(typeof(ThirdPersonEmoteController), "OnStartCustomEmoteLocal")] [HarmonyPostfix] private static void OnStartCustomEmoteLocalPostfix() { IsLocalCustomEmoteActive = true; ReservedPlayerData localPlayerData = ReservedPlayerData.localPlayerData; if (localPlayerData == null) { return; } PlayerControllerB playerController = localPlayerData.playerController; if ((Object)(object)playerController == (Object)null) { return; } int num = Mathf.Min(localPlayerData.reservedHotbarStartIndex, playerController.ItemSlots.Length); ReservedPlayerData playerData; ReservedItemData itemData; for (int i = 0; i < num; i++) { if (i == playerController.currentItemSlot) { continue; } GrabbableObject val = playerController.ItemSlots[i]; if ((Object)(object)val == (Object)null || !GrabbableObjectPatches.TryGetHolsterData(val, playerController, out playerData, out itemData)) { continue; } MeshRenderer[] renderers = RendererCache.GetRenderers(val); foreach (MeshRenderer val2 in renderers) { ((Renderer)val2).enabled = true; if (RendererCache.TryGetOriginalLayer(((Component)val2).gameObject, out var layer) && !GrabbableObjectPatches.IsLayerInLocalCameraMask(((Component)val2).gameObject.layer)) { ((Component)val2).gameObject.layer = layer; } } } if (playerController.currentItemSlot == 50) { return; } GrabbableObject itemOnlySlot = playerController.ItemOnlySlot; if ((Object)(object)itemOnlySlot == (Object)null || !GrabbableObjectPatches.TryGetHolsterData(itemOnlySlot, playerController, out playerData, out itemData)) { return; } MeshRenderer[] renderers2 = RendererCache.GetRenderers(itemOnlySlot); foreach (MeshRenderer val3 in renderers2) { ((Renderer)val3).enabled = true; if (RendererCache.TryGetOriginalLayer(((Component)val3).gameObject, out var layer2) && !GrabbableObjectPatches.IsLayerInLocalCameraMask(((Component)val3).gameObject.layer)) { ((Component)val3).gameObject.layer = layer2; } } } [HarmonyPatch(typeof(ThirdPersonEmoteController), "OnStopCustomEmoteLocal")] [HarmonyPostfix] private static void OnStopCustomEmoteLocalPostfix() { IsLocalCustomEmoteActive = false; ReservedPlayerData localPlayerData = ReservedPlayerData.localPlayerData; if (localPlayerData == null) { return; } PlayerControllerB playerController = localPlayerData.playerController; if ((Object)(object)playerController == (Object)null) { return; } int num = Mathf.Min(localPlayerData.reservedHotbarStartIndex, playerController.ItemSlots.Length); ReservedPlayerData playerData; ReservedItemData itemData; int layer; for (int i = 0; i < num; i++) { if (i == playerController.currentItemSlot) { continue; } GrabbableObject val = playerController.ItemSlots[i]; if ((Object)(object)val == (Object)null || !GrabbableObjectPatches.TryGetHolsterData(val, playerController, out playerData, out itemData)) { continue; } MeshRenderer[] renderers = RendererCache.GetRenderers(val); foreach (MeshRenderer val2 in renderers) { if (RendererCache.TryGetOriginalLayer(((Component)val2).gameObject, out layer) && GrabbableObjectPatches.IsLayerInLocalCameraMask(((Component)val2).gameObject.layer)) { ((Component)val2).gameObject.layer = 23; } } HolsterVisibilityCache.RefreshItem(val); } if (playerController.currentItemSlot == 50) { return; } GrabbableObject itemOnlySlot = playerController.ItemOnlySlot; if ((Object)(object)itemOnlySlot == (Object)null || !GrabbableObjectPatches.TryGetHolsterData(itemOnlySlot, playerController, out playerData, out itemData)) { return; } MeshRenderer[] renderers2 = RendererCache.GetRenderers(itemOnlySlot); foreach (MeshRenderer val3 in renderers2) { if (RendererCache.TryGetOriginalLayer(((Component)val3).gameObject, out layer) && GrabbableObjectPatches.IsLayerInLocalCameraMask(((Component)val3).gameObject.layer)) { ((Component)val3).gameObject.layer = 23; } } HolsterVisibilityCache.RefreshItem(itemOnlySlot); } [HarmonyPatch(typeof(PlayerControllerB), "UseUtilitySlot_performed")] [HarmonyPrefix] private static bool UseUtilitySlot_performedPrefix(PlayerControllerB __instance) { if (!IsLocalCustomEmoteActive) { return true; } PlayerControllerB val = StartOfRound.Instance?.localPlayerController; if ((Object)(object)__instance != (Object)(object)val) { return true; } return false; } } } namespace ReservedSlotPositionsForInventory.Cache { internal static class FlashlightPriorityCache { private static readonly Dictionary<int, long> ToggleOrderByItemId = new Dictionary<int, long>(); private static long NextToggleOrder; internal static void MarkToggledOn(FlashlightItem flashlight) { if (!((Object)(object)flashlight == (Object)null)) { ToggleOrderByItemId[((Object)flashlight).GetInstanceID()] = NextToggleOrder; NextToggleOrder++; } } internal static void MarkToggledOff(FlashlightItem flashlight) { if (!((Object)(object)flashlight == (Object)null)) { ToggleOrderByItemId.Remove(((Object)flashlight).GetInstanceID()); } } internal static bool TryGetToggleOrder(FlashlightItem flashlight, out long order) { order = 0L; return (Object)(object)flashlight != (Object)null && ToggleOrderByItemId.TryGetValue(((Object)flashlight).GetInstanceID(), out order); } internal static void Clear() { ToggleOrderByItemId.Clear(); NextToggleOrder = 0L; } } internal readonly struct HolsterBoneKey : IEquatable<HolsterBoneKey> { private readonly int _playerId; private readonly PlayerBone _bone; internal HolsterBoneKey(PlayerControllerB playerController, PlayerBone bone) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) _playerId = ((Object)playerController).GetInstanceID(); _bone = bone; } public bool Equals(HolsterBoneKey other) { //IL_0010: 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) return _playerId == other._playerId && _bone == other._bone; } public override bool Equals(object obj) { return obj is HolsterBoneKey other && Equals(other); } public override int GetHashCode() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown return HashCode.Combine(_playerId, (int)_bone); } } internal static class HolsterVisibilityCache { internal static readonly Dictionary<HolsterBoneKey, List<GrabbableObject>> ItemsByBone = new Dictionary<HolsterBoneKey, List<GrabbableObject>>(); internal static readonly Dictionary<int, HolsterBoneKey> KeyByItemId = new Dictionary<int, HolsterBoneKey>(); internal static readonly Dictionary<ulong, long> SyncedFirstPickupOrderByNetworkObjectId = new Dictionary<ulong, long>(); internal static bool UsesSyncedFirstPickupOrdering => ConfigManager.BoneVisibilityModeConfig.Value == BoneVisibilityMode.FirstPickedUpMode || ConfigManager.BoneVisibilityModeConfig.Value == BoneVisibilityMode.LastItemHeldMode; internal static void RegisterPocketedItem(PlayerControllerB playerController, PlayerBone bone, GrabbableObject item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)item).GetInstanceID(); HolsterBoneKey holsterBoneKey = new HolsterBoneKey(playerController, bone); if (KeyByItemId.TryGetValue(instanceID, out var value) && !value.Equals(holsterBoneKey) && ItemsByBone.TryGetValue(value, out var value2)) { RemoveDeadAndItem(value2, item); if (value2.Count == 0) { ItemsByBone.Remove(value); } else { RefreshVisibleItem(value2); } } if (!ItemsByBone.TryGetValue(holsterBoneKey, out var value3)) { value3 = new List<GrabbableObject>(); ItemsByBone[holsterBoneKey] = value3; } RemoveDeadAndItem(value3, item); value3.Add(item); KeyByItemId[instanceID] = holsterBoneKey; RefreshVisibleItem(value3); } internal static void RemoveItem(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return; } int instanceID = ((Object)item).GetInstanceID(); if (!KeyByItemId.TryGetValue(instanceID, out var value)) { SetItemVisible(item, visible: true); return; } KeyByItemId.Remove(instanceID); if (!ItemsByBone.TryGetValue(value, out var value2)) { SetItemVisible(item, visible: true); return; } RemoveDeadAndItem(value2, item); SetItemVisible(item, visible: true); if (value2.Count == 0) { ItemsByBone.Remove(value); } else { RefreshVisibleItem(value2); } } internal static void RemoveItemAndForgetPriority(GrabbableObject item) { RemoveItem(item); if (TryGetNetworkObjectId(item, out var networkObjectId)) { RemoveSyncedFirstPickupOrder(networkObjectId); } } internal static bool HasSyncedFirstPickupOrder(ulong networkObjectId) { return SyncedFirstPickupOrderByNetworkObjectId.ContainsKey(networkObjectId); } internal static void ApplySyncedFirstPickupOrder(ulong networkObjectId, long order) { SyncedFirstPickupOrderByNetworkObjectId[networkObjectId] = order; GrabbableObject grabbableObjectByNetworkId = GetGrabbableObjectByNetworkId(networkObjectId); if ((Object)(object)grabbableObjectByNetworkId != (Object)null) { RefreshItem(grabbableObjectByNetworkId); } } internal static void RemoveSyncedFirstPickupOrder(ulong networkObjectId) { if (SyncedFirstPickupOrderByNetworkObjectId.Remove(networkObjectId)) { GrabbableObject grabbableObjectByNetworkId = GetGrabbableObjectByNetworkId(networkObjectId); if ((Object)(object)grabbableObjectByNetworkId != (Object)null) { RefreshItem(grabbableObjectByNetworkId); } } } internal static void RefreshItem(GrabbableObject item) { if (!((Object)(object)item == (Object)null)) { int instanceID = ((Object)item).GetInstanceID(); if (KeyByItemId.TryGetValue(instanceID, out var value) && ItemsByBone.TryGetValue(value, out var value2)) { RefreshVisibleItem(value2); } } } internal static void Clear() { ItemsByBone.Clear(); KeyByItemId.Clear(); SyncedFirstPickupOrderByNetworkObjectId.Clear(); } private static void RefreshVisibleItem(List<GrabbableObject> items) { RemoveDead(items); if (items.Count != 0) { GrabbableObject preferredVisibleItem = GetPreferredVisibleItem(items); for (int i = 0; i < items.Count; i++) { SetItemVisible(items[i], (Object)(object)items[i] == (Object)(object)preferredVisibleItem); } } } private static GrabbableObject GetPreferredVisibleItem(List<GrabbableObject> items) { if (TryGetPriorityFlashlight(items, out var priorityFlashlight)) { return priorityFlashlight; } BoneVisibilityMode value = ConfigManager.BoneVisibilityModeConfig.Value; if (1 == 0) { } GrabbableObject result = (GrabbableObject)(value switch { BoneVisibilityMode.FirstPickedUpMode => GetFirstPickedUpItem(items), BoneVisibilityMode.LastItemHeldMode => GetLastItemHeldItem(items), _ => GetFirstPickedUpItem(items), }); if (1 == 0) { } return result; } private static bool TryGetPriorityFlashlight(List<GrabbableObject> items, out GrabbableObject priorityFlashlight) { priorityFlashlight = null; FlashlightItem val = null; long num = long.MinValue; bool flag = false; for (int i = 0; i < items.Count; i++) { GrabbableObject obj = items[i]; FlashlightItem val2 = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null); if (val2 == null || !IsPriorityFlashlight(val2)) { continue; } if (FlashlightPriorityCache.TryGetToggleOrder(val2, out var order)) { if (!flag || order > num) { val = val2; num = order; flag = true; } } else if ((Object)(object)val == (Object)null) { val = val2; } } priorityFlashlight = (GrabbableObject)(object)val; return (Object)(object)priorityFlashlight != (Object)null; } private static bool IsPriorityFlashlight(FlashlightItem flashlight) { if (!((GrabbableObject)flashlight).isBeingUsed) { return false; } if (flashlight.usingPlayerHelmetLight) { return true; } PlayerControllerB playerHeldBy = ((GrabbableObject)flashlight).playerHeldBy; return (Object)(object)playerHeldBy != (Object)null && (Object)(object)playerHeldBy.pocketedFlashlight == (Object)(object)flashlight; } private static GrabbableObject GetFirstPickedUpItem(List<GrabbableObject> items) { GrabbableObject val = items[0]; long num = GetSyncedFirstPickupOrder(val); for (int i = 1; i < items.Count; i++) { GrabbableObject val2 = items[i]; long syncedFirstPickupOrder = GetSyncedFirstPickupOrder(val2); if (syncedFirstPickupOrder < num) { val = val2; num = syncedFirstPickupOrder; } } return val; } private static GrabbableObject GetLastItemHeldItem(List<GrabbableObject> items) { GrabbableObject val = items[0]; long num = GetSyncedFirstPickupOrder(val); for (int i = 1; i < items.Count; i++) { GrabbableObject val2 = items[i]; long syncedFirstPickupOrder = GetSyncedFirstPickupOrder(val2); if (syncedFirstPickupOrder > num) { val = val2; num = syncedFirstPickupOrder; } } return val; } private static long GetSyncedFirstPickupOrder(GrabbableObject item) { if (!TryGetNetworkObjectId(item, out var networkObjectId)) { return long.MaxValue; } long value; return SyncedFirstPickupOrderByNetworkObjectId.TryGetValue(networkObjectId, out value) ? value : long.MaxValue; } private static void RemoveDead(List<GrabbableObject> items) { for (int num = items.Count - 1; num >= 0; num--) { if (!((Object)(object)items[num] != (Object)null)) { items.RemoveAt(num); } } } private static void RemoveDeadAndItem(List<GrabbableObject> items, GrabbableObject item) { for (int num = items.Count - 1; num >= 0; num--) { GrabbableObject val = items[num]; if (!((Object)(object)val != (Object)null) || !((Object)(object)val != (Object)(object)item)) { items.RemoveAt(num); } } } private static bool TryGetNetworkObjectId(GrabbableObject item, out ulong networkObjectId) { networkObjectId = 0uL; if ((Object)(object)item == (Object)null || (Object)(object)((NetworkBehaviour)item).NetworkObject == (Object)null || !((NetworkBehaviour)item).NetworkObject.IsSpawned) { return false; } networkObjectId = ((NetworkBehaviour)item).NetworkObject.NetworkObjectId; return true; } private static GrabbableObject GetGrabbableObjectByNetworkId(ulong networkObjectId) { NetworkManager singleton = NetworkManager.Singleton; if (((singleton != null) ? singleton.SpawnManager : null) == null) { return null; } if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(networkObjectId, out var value)) { return null; } return ((Component)value).GetComponent<GrabbableObject>(); } private static void SetItemVisible(GrabbableObject item, bool visible) { if ((Object)(object)item == (Object)null) { return; } item.EnableItemMeshes(visible); MeshRenderer[] renderers = RendererCache.GetRenderers(item); foreach (MeshRenderer val in renderers) { if ((Object)(object)val != (Object)null) { ((Renderer)val).enabled = visible; } } } } internal static class RendererCache { private static readonly Dictionary<int, MeshRenderer[]> RenderersByItem = new Dictionary<int, MeshRenderer[]>(); private static readonly Dictionary<GameObject, int> OriginalLayers = new Dictionary<GameObject, int>(); internal static MeshRenderer[] GetRenderers(GrabbableObject item) { int instanceID = ((Object)item).GetInstanceID(); if (RenderersByItem.TryGetValue(instanceID, out var value) && IsValid(value)) { return value; } MeshRenderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<MeshRenderer>(true); List<MeshRenderer> list = new List<MeshRenderer>(componentsInChildren.Length); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Object)val).name.IndexOf("ScanNode", StringComparison.Ordinal) < 0 && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger") && ((Component)val).gameObject.layer != LayerMask.NameToLayer("Enemies")) { list.Add(val); } } MeshRenderer[] array = list.ToArray(); RenderersByItem[instanceID] = array; return array; } internal static void RememberLayer(GameObject gameObject) { if (!OriginalLayers.ContainsKey(gameObject)) { OriginalLayers[gameObject] = gameObject.layer; } } internal static bool TryGetOriginalLayer(GameObject gameObject, out int layer) { return OriginalLayers.TryGetValue(gameObject, out layer); } internal static void ForgetLayer(GameObject gameObject) { OriginalLayers.Remove(gameObject); } internal static void Clear() { RenderersByItem.Clear(); OriginalLayers.Clear(); } private static bool IsValid(MeshRenderer[] renderers) { for (int i = 0; i < renderers.Length; i++) { if ((Object)(object)renderers[i] == (Object)null) { return false; } } return true; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace ReservedSlotPositionsForInventory.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }