Decompiled source of MoreInventorySlots v1.0.1

MoreInventorySlots.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MoreInventorySlots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreInventorySlots")]
[assembly: AssemblyTitle("MoreInventorySlots")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreInventorySlots
{
	[BepInPlugin("nickklmao.moreinventoryslots", "More Inventory Slots", "1.0.1")]
	internal sealed class Entry : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<Action<InventoryUI>, InventoryUI> <0>__InventoryUI_StartHook;

			public static Action<Action<StatsManager, string, string, int, bool>, StatsManager, string, string, int, bool> <1>__StatsManager_PlayerInventoryUpdateHook;

			public static Action<Action<ItemEquippable, int, int>, ItemEquippable, int, int> <2>__ItemEquippable_RPC_RequestEquip;

			public static Action<Action<MainMenuOpen>, MainMenuOpen> <3>__MainMenuOpen_StartHook;

			public static Manipulator <4>__Inventory_StartILHook;

			public static Manipulator <5>__InventorySpot_UpdateILHook;

			public static Manipulator <6>__PunManager_SetItemNameLOGIC_ILHook;
		}

		private const string MOD_NAME = "More Inventory Slots";

		internal static readonly ManualLogSource logger = Logger.CreateLogSource("More Inventory Slots");

		private static readonly Dictionary<string, Dictionary<int, int>> serverMonitoredInventoryItems = new Dictionary<string, Dictionary<int, int>>();

		private static ConfigEntry<int> inventorySlots;

		private static ConfigEntry<bool> hostProtection;

		private static ConfigEntry<bool> keepItemsInTruck;

		private static void InventoryUI_StartHook(Action<InventoryUI> orig, InventoryUI self)
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			orig(self);
			if (inventorySlots.Value == 3)
			{
				return;
			}
			List<GameObject> list = AccessTools.Field(typeof(InventoryUI), "allChildren").GetValue(self) as List<GameObject>;
			float num = (float)(-(inventorySlots.Value * 40)) / 2f + 20f;
			if (inventorySlots.Value < 3)
			{
				for (int i = 0; i < 3; i++)
				{
					GameObject gameObject = ((Component)((Component)self).transform.Find($"Inventory Spot {i + 1}")).gameObject;
					if (i < inventorySlots.Value)
					{
						gameObject.transform.localPosition = Vector2.op_Implicit(new Vector2(num + (float)i * 40f, -175.3f));
						continue;
					}
					gameObject.SetActive(false);
					list.Remove(gameObject);
				}
				return;
			}
			Transform val = ((Component)self).transform.Find("Inventory Spot 1");
			for (int j = 0; j < inventorySlots.Value; j++)
			{
				if (j < 3)
				{
					((Component)self).transform.Find($"Inventory Spot {j + 1}").localPosition = Vector2.op_Implicit(new Vector2(num + (float)j * 40f, -175.3f));
					continue;
				}
				Transform val2 = Object.Instantiate<Transform>(val, val.parent);
				((Object)val2).name = $"Inventory Spot {j + 1}";
				InventorySpot component = ((Component)val2).GetComponent<InventorySpot>();
				component.inventorySpotIndex = j;
				TextMeshProUGUI component2 = ((Component)val2.Find("Numbers")).GetComponent<TextMeshProUGUI>();
				string text2 = (((TMP_Text)component.noItem).text = (j + 1).ToString());
				((TMP_Text)component2).text = text2;
				val2.localPosition = Vector2.op_Implicit(new Vector2(num + (float)j * 40f, -175.3f));
				list.Add(((Component)val2).gameObject);
			}
		}

		private static void StatsManager_PlayerInventoryUpdateHook(Action<StatsManager, string, string, int, bool> orig, StatsManager self, string steamID, string itemName, int spot, bool sync)
		{
			orig(self, steamID, itemName, spot, sync);
			if (!SemiFunc.IsMasterClientOrSingleplayer() || spot < 3)
			{
				return;
			}
			Dictionary<int, int> value;
			bool flag = serverMonitoredInventoryItems.TryGetValue(steamID, out value);
			if (string.IsNullOrEmpty(itemName))
			{
				if (flag)
				{
					value.Remove(spot);
					if (value.Count == 0)
					{
						serverMonitoredInventoryItems.Remove(steamID);
					}
				}
			}
			else
			{
				if (!flag)
				{
					serverMonitoredInventoryItems.Add(steamID, value = new Dictionary<int, int>());
				}
				value[spot] = itemName.GetHashCode();
			}
		}

		private static void ItemEquippable_RPC_RequestEquip(Action<ItemEquippable, int, int> orig, ItemEquippable self, int spotIndex, int physGrabberPhotonView)
		{
			StackFrame[] frames = new StackTrace().GetFrames();
			if ((frames == null || !frames.Any((StackFrame frame) => frame.GetMethod().Name == "SetItemNameLOGIC") || !keepItemsInTruck.Value) && (!SemiFunc.IsMultiplayer() || !hostProtection.Value || spotIndex < inventorySlots.Value))
			{
				orig(self, spotIndex, physGrabberPhotonView);
			}
		}

		private static void MainMenuOpen_StartHook(Action<MainMenuOpen> orig, MainMenuOpen self)
		{
			orig(self);
			serverMonitoredInventoryItems.Clear();
		}

		private static void Inventory_StartILHook(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 3)
			});
			val.Remove();
			val.Emit<Entry>(OpCodes.Ldsfld, "inventorySlots");
			val.Emit<ConfigEntry<int>>(OpCodes.Callvirt, "get_Value");
			val.Emit(OpCodes.Ldc_I4_3);
			val.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(Math), "Max", new Type[2]
			{
				typeof(int),
				typeof(int)
			}, (Type[])null));
		}

		private static void InventorySpot_UpdateILHook(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction instruction) => ILPatternMatchingExt.MatchLdfld<InventorySpot>(instruction, "currentState")
			});
			val.EmitDelegate<Action<InventorySpot>>((Action<InventorySpot>)delegate(InventorySpot inventorySpot)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				Key val2 = (Key)((inventorySpot.inventorySpotIndex == 9) ? 50 : ((int)Enum.Parse<Key>($"Digit{inventorySpot.inventorySpotIndex + 1}")));
				if (((ButtonControl)Keyboard.current[val2]).wasPressedThisFrame)
				{
					AccessTools.Method(typeof(InventorySpot), "HandleInput", (Type[])null, (Type[])null).Invoke(inventorySpot, null);
				}
			});
			val.Emit(OpCodes.Ldarg_0);
		}

		private static void PunManager_SetItemNameLOGIC_ILHook(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0063: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ILLabel returnLabel = null;
			val.GotoNext(new Func<Instruction, bool>[2]
			{
				(Instruction instruction) => ILPatternMatchingExt.MatchLdloc(instruction, 5),
				(Instruction instruction) => ILPatternMatchingExt.MatchBrfalse(instruction, ref returnLabel) && ILPatternMatchingExt.MatchRet(returnLabel.Target)
			});
			il.Instrs[val.Index].OpCode = OpCodes.Ldloc_2;
			il.Instrs[val.Index].Operand = null;
			int index = val.Index;
			val.Index = index + 1;
			val.Emit(OpCodes.Ldloc, 5);
			val.Emit(OpCodes.Ldloc, 4);
			val.EmitDelegate<Func<ItemEquippable, bool, int, bool>>((Func<ItemEquippable, bool, int, bool>)delegate(ItemEquippable itemEquippable, bool hasInInventory, int hashCode)
			{
				if (hasInInventory || !Object.op_Implicit((Object)(object)itemEquippable))
				{
					return false;
				}
				foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
				{
					if (serverMonitoredInventoryItems.TryGetValue(SemiFunc.PlayerGetSteamID(item), out var value) && value.ContainsValue(hashCode))
					{
						itemEquippable.RequestEquip(value.First((KeyValuePair<int, int> element) => element.Value == hashCode).Key, SemiFunc.IsMultiplayer() ? item.photonView.ViewID : (-1));
						return true;
					}
				}
				return false;
			});
			val.Emit(OpCodes.Brtrue_S, (object)returnLabel);
			val.Emit(OpCodes.Ldloc, 5);
		}

		private void Awake()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Expected O, but got Unknown
			inventorySlots = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Number Of Slots", 3, new ConfigDescription("How many inventory slots do you want? (Updates after a round changes)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
			hostProtection = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Host Protection", true, new ConfigDescription("Should clients be prevented from picking up more items than the configured amount above (requires host)", (AcceptableValueBase)null, Array.Empty<object>()));
			keepItemsInTruck = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Keep Items In Truck", false, new ConfigDescription("After a round changes, should items return to the truck instead of the players?", (AcceptableValueBase)null, Array.Empty<object>()));
			logger.LogDebug((object)"Hooking `InventoryUI.Start`");
			new Hook((MethodBase)AccessTools.Method(typeof(InventoryUI), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<InventoryUI>, InventoryUI>(InventoryUI_StartHook));
			logger.LogDebug((object)"Hooking `StatsManager.PlayerInventoryUpdate`");
			new Hook((MethodBase)AccessTools.Method(typeof(StatsManager), "PlayerInventoryUpdate", (Type[])null, (Type[])null), (Delegate)new Action<Action<StatsManager, string, string, int, bool>, StatsManager, string, string, int, bool>(StatsManager_PlayerInventoryUpdateHook));
			logger.LogDebug((object)"Hooking `ItemEquippable.RPC_RequestEquip`");
			new Hook((MethodBase)AccessTools.Method(typeof(ItemEquippable), "RPC_RequestEquip", (Type[])null, (Type[])null), (Delegate)new Action<Action<ItemEquippable, int, int>, ItemEquippable, int, int>(ItemEquippable_RPC_RequestEquip));
			logger.LogDebug((object)"Hooking `MainMenuOpen.Start`");
			new Hook((MethodBase)AccessTools.Method(typeof(MainMenuOpen), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<MainMenuOpen>, MainMenuOpen>(MainMenuOpen_StartHook));
			logger.LogDebug((object)"Hooking `Inventory.Start`");
			MethodInfo methodInfo = AccessTools.Method(typeof(Inventory), "Start", (Type[])null, (Type[])null);
			object obj = <>O.<4>__Inventory_StartILHook;
			if (obj == null)
			{
				Manipulator val = Inventory_StartILHook;
				<>O.<4>__Inventory_StartILHook = val;
				obj = (object)val;
			}
			new ILHook((MethodBase)methodInfo, (Manipulator)obj);
			logger.LogDebug((object)"Hooking `InventorySpot.Update`");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(InventorySpot), "Update", (Type[])null, (Type[])null);
			object obj2 = <>O.<5>__InventorySpot_UpdateILHook;
			if (obj2 == null)
			{
				Manipulator val2 = InventorySpot_UpdateILHook;
				<>O.<5>__InventorySpot_UpdateILHook = val2;
				obj2 = (object)val2;
			}
			new ILHook((MethodBase)methodInfo2, (Manipulator)obj2);
			logger.LogDebug((object)"Hooking `PunManager.SetItemNameLOGIC`");
			MethodInfo methodInfo3 = AccessTools.Method(typeof(PunManager), "SetItemNameLOGIC", (Type[])null, (Type[])null);
			object obj3 = <>O.<6>__PunManager_SetItemNameLOGIC_ILHook;
			if (obj3 == null)
			{
				Manipulator val3 = PunManager_SetItemNameLOGIC_ILHook;
				<>O.<6>__PunManager_SetItemNameLOGIC_ILHook = val3;
				obj3 = (object)val3;
			}
			new ILHook((MethodBase)methodInfo3, (Manipulator)obj3);
		}
	}
}