Decompiled source of BagExpander v1.0.6

HiarlyScripter-BagExpander/BagExpander.dll

Decompiled 2 days 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 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.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6+4c5c8a3b8c46ad1f7fbe4a9c8fa698d61341058e")]
[assembly: AssemblyProduct("BagExpander")]
[assembly: AssemblyTitle("BagExpander")]
[assembly: AssemblyVersion("1.0.6.0")]
namespace BagExpander;

[BepInPlugin("com.hiarlyscripter.bagexpander", "Bag Expander", "1.0.6")]
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.6 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 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);
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(InventoryUI), "Awake")]
	private static void PrepareSlotsBeforeLayout(InventoryUI __instance)
	{
		int value = BagExpanderPlugin.SlotCount.Value;
		if (value == 3)
		{
			return;
		}
		List<InventorySpot> list = (from s in ((Component)__instance).GetComponentsInChildren<InventorySpot>(true)
			orderby s.inventorySpotIndex
			select s).ToList();
		if (list.Count == 0)
		{
			BagExpanderPlugin.Log.LogWarning((object)"InventoryUI sem InventorySpot; slots não ajustados.");
			return;
		}
		if (value < 3)
		{
			for (int num = value; num < list.Count; num++)
			{
				((Component)list[num]).gameObject.SetActive(false);
			}
			return;
		}
		InventorySpot val = list[0];
		for (int num2 = list.Count; num2 < value; num2++)
		{
			InventorySpot obj = Object.Instantiate<InventorySpot>(val, ((Component)val).transform.parent);
			((Object)obj).name = $"Inventory Spot {num2 + 1}";
			obj.inventorySpotIndex = num2;
			((Component)obj).gameObject.SetActive(true);
			string template = ((num2 == 9) ? "0" : (num2 + 1).ToString());
			InputGlyphText[] componentsInChildren = ((Component)obj).GetComponentsInChildren<InputGlyphText>(true);
			for (int num3 = 0; num3 < componentsInChildren.Length; num3++)
			{
				componentsInChildren[num3].SetTemplate(template);
			}
		}
		BagExpanderPlugin.Log.LogInfo((object)$"Slots de inventário: {value} (UI criada antes do layout).");
	}

	[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);
	}
}