Decompiled source of BagExpander v1.0.5

HiarlyScripter-BagExpander/BagExpander.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 Photon.Pun;
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("BagExpander")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BagExpander")]
[assembly: AssemblyTitle("BagExpander")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BagExpander;

[BepInPlugin("com.hiarlyscripter.bagexpander", "Bag Expander", "1.0.0")]
public sealed class BagExpanderPlugin : BaseUnityPlugin
{
	internal static ConfigEntry<int> SlotCount;

	internal static ConfigEntry<bool> LeaveInBase;

	internal static ConfigEntry<bool> HostControls;

	internal static BagExpanderPlugin Instance { get; private set; }

	internal static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		SlotCount = ((BaseUnityPlugin)this).Config.Bind<int>("Slots", "SlotCount", 3, new ConfigDescription("Número de slots de inventário disponíveis. Mínimo: 0 (sem inventário), máximo: 10, padrão do jogo: 3. Requer reinício da rodada para aplicar. Editável pelo REPOConfig.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
		LeaveInBase = ((BaseUnityPlugin)this).Config.Bind<bool>("Slots", "LeaveInBase", false, "true  = ao trocar de rodada, itens nos slots extras (acima de 3) ficam na base.\nfalse = itens retornam equipados ao jogador na próxima rodada (padrão).");
		HostControls = ((BaseUnityPlugin)this).Config.Bind<bool>("Multiplayer", "HostControls", true, "true  = o HOST define o número máximo de slots para todos os jogadores. Clientes não conseguem equipar itens além do SlotCount do host, mesmo que tenham o mod com um valor maior configurado.\nfalse = cada jogador usa livremente seu próprio SlotCount. Todos os jogadores precisam ter o mod instalado para se beneficiar.\nIMPORTANTE: este mod deve ser instalado por cada jogador individualmente. O host não consegue forçar slots extras em clientes que não têm o mod.");
		new Harmony("com.hiarlyscripter.bagexpander").PatchAll(typeof(SlotPatches));
		Log.LogInfo((object)"Bag Expander v1.0.0 carregado.");
	}
}
internal static class EquipTracker
{
	private static readonly Dictionary<string, Dictionary<int, int>> _registry = new Dictionary<string, Dictionary<int, int>>();

	internal static void Record(string steamID, int slot, int nameHash)
	{
		if (!_registry.TryGetValue(steamID, out var value))
		{
			value = new Dictionary<int, int>();
			_registry[steamID] = value;
		}
		value[slot] = nameHash;
	}

	internal static void Erase(string steamID, int slot)
	{
		if (_registry.TryGetValue(steamID, out var value))
		{
			value.Remove(slot);
			if (value.Count == 0)
			{
				_registry.Remove(steamID);
			}
		}
	}

	internal static void Reset()
	{
		_registry.Clear();
	}

	internal static bool Lookup(int nameHash, out string steamID, out int slot, List<PlayerAvatar> players)
	{
		foreach (PlayerAvatar player in players)
		{
			string text = SemiFunc.PlayerGetSteamID(player);
			if (!_registry.TryGetValue(text, out var value))
			{
				continue;
			}
			foreach (KeyValuePair<int, int> item in value)
			{
				if (item.Value == nameHash)
				{
					steamID = text;
					slot = item.Key;
					return true;
				}
			}
		}
		steamID = null;
		slot = -1;
		return false;
	}
}
[HarmonyPatch]
internal static class SlotPatches
{
	private static readonly FieldInfo _spotsListField = AccessTools.Field(typeof(Inventory), "inventorySpots");

	private static readonly FieldInfo _uiChildrenField = AccessTools.Field(typeof(InventoryUI), "allChildren");

	private static readonly MethodInfo _handleInputMethod = AccessTools.Method(typeof(InventorySpot), "HandleInput", (Type[])null, (Type[])null);

	[HarmonyPostfix]
	[HarmonyPatch(typeof(Inventory), "Awake")]
	private static void ExpandSlotList(Inventory __instance)
	{
		List<InventorySpot> list = (List<InventorySpot>)_spotsListField.GetValue(__instance);
		int num = Math.Max(BagExpanderPlugin.SlotCount.Value, 3);
		while (list.Count < num)
		{
			list.Add(null);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(InventoryUI), "Start")]
	private static void AdjustSlotVisuals(InventoryUI __instance)
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		int value = BagExpanderPlugin.SlotCount.Value;
		if (value == 3)
		{
			return;
		}
		Transform transform = ((Component)__instance).transform;
		List<GameObject> list = _uiChildrenField?.GetValue(__instance) as List<GameObject>;
		float num = 40f;
		float num2 = (0f - (float)value * num) / 2f + num / 2f;
		if (value < 3)
		{
			for (int i = 0; i < 3; i++)
			{
				Transform val = transform.Find($"Inventory Spot {i + 1}");
				if (!((Object)(object)val == (Object)null))
				{
					if (i < value)
					{
						val.localPosition = new Vector3(num2 + (float)i * num, val.localPosition.y, 0f);
						continue;
					}
					((Component)val).gameObject.SetActive(false);
					list?.Remove(((Component)val).gameObject);
				}
			}
			return;
		}
		Transform val2 = transform.Find("Inventory Spot 1") ?? ((transform.childCount > 0) ? transform.GetChild(0) : null);
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		for (int j = 0; j < value; j++)
		{
			if (j < 3)
			{
				Transform val3 = transform.Find($"Inventory Spot {j + 1}");
				if ((Object)(object)val3 != (Object)null)
				{
					val3.localPosition = new Vector3(num2 + (float)j * num, val3.localPosition.y, 0f);
				}
				continue;
			}
			Transform val4 = Object.Instantiate<Transform>(val2, val2.parent);
			((Object)val4).name = $"Inventory Spot {j + 1}";
			InventorySpot component = ((Component)val4).GetComponent<InventorySpot>();
			component.inventorySpotIndex = j;
			Transform obj = val4.Find("Numbers");
			TextMeshProUGUI val5 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
			if ((Object)(object)val5 != (Object)null)
			{
				((TMP_Text)val5).text = (j + 1).ToString();
			}
			if ((Object)(object)component.noItem != (Object)null)
			{
				((TMP_Text)component.noItem).text = (j + 1).ToString();
			}
			val4.localPosition = new Vector3(num2 + (float)j * num, val2.localPosition.y, 0f);
			list?.Add(((Component)val4).gameObject);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(InventorySpot), "Update")]
	private static void ExtraSlotKeyInput(InventorySpot __instance)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		int inventorySpotIndex = __instance.inventorySpotIndex;
		if (inventorySpotIndex >= 3 && inventorySpotIndex < BagExpanderPlugin.SlotCount.Value)
		{
			Key val = (Key)((inventorySpotIndex == 9) ? 50 : ((int)(Key)Enum.Parse(typeof(Key), $"Digit{inventorySpotIndex + 1}")));
			if (((ButtonControl)Keyboard.current[val]).wasPressedThisFrame)
			{
				_handleInputMethod.Invoke(__instance, null);
			}
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(StatsManager), "PlayerInventoryUpdate")]
	private static void TrackExtraEquip(string _steamID, string itemName, int spot)
	{
		if (SemiFunc.IsMasterClientOrSingleplayer() && spot >= 3)
		{
			if (string.IsNullOrEmpty(itemName))
			{
				EquipTracker.Erase(_steamID, spot);
			}
			else
			{
				EquipTracker.Record(_steamID, spot, itemName.GetHashCode());
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(ItemEquippable), "RPC_RequestEquip")]
	private static bool CheckSlotLimit(int spotIndex)
	{
		if (!SemiFunc.IsMultiplayer())
		{
			return true;
		}
		if (!BagExpanderPlugin.HostControls.Value)
		{
			return true;
		}
		return spotIndex < BagExpanderPlugin.SlotCount.Value;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(MainMenuOpen), "Start")]
	private static void ClearStateOnMenu()
	{
		EquipTracker.Reset();
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(PunManager), "SetItemNameLOGIC", new Type[]
	{
		typeof(string),
		typeof(int),
		typeof(ItemAttributes)
	})]
	private static void RestoreExtraSlotItems(PunManager __instance, string _name, int photonViewID, ItemAttributes _itemAttributes)
	{
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		ItemAttributes val = _itemAttributes;
		if ((Object)(object)val == (Object)null && SemiFunc.IsMultiplayer())
		{
			PhotonView val2 = PhotonView.Find(photonViewID);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			val = ((Component)val2).GetComponent<ItemAttributes>();
		}
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ItemEquippable component = ((Component)val).GetComponent<ItemEquippable>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		List<PlayerAvatar> list = SemiFunc.PlayerGetList();
		if (!EquipTracker.Lookup(_name.GetHashCode(), out var sid, out var slot, list))
		{
			return;
		}
		if (!BagExpanderPlugin.LeaveInBase.Value)
		{
			int num = -1;
			if (SemiFunc.IsMultiplayer())
			{
				PlayerAvatar val3 = ((IEnumerable<PlayerAvatar>)list).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => SemiFunc.PlayerGetSteamID(p) == sid));
				if ((Object)(object)val3 != (Object)null)
				{
					num = val3.photonView.ViewID;
				}
			}
			component.RequestEquip(slot, num);
		}
		EquipTracker.Erase(sid, slot);
	}
}