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 SlotCount; internal static ConfigEntry LeaveInBase; internal static ConfigEntry 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("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(0, 10), Array.Empty())); LeaveInBase = ((BaseUnityPlugin)this).Config.Bind("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("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> _registry = new Dictionary>(); internal static void Record(string steamID, int slot, int nameHash) { if (!_registry.TryGetValue(steamID, out var value)) { value = new Dictionary(); _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 players) { foreach (PlayerAvatar player in players) { string text = SemiFunc.PlayerGetSteamID(player); if (!_registry.TryGetValue(text, out var value)) { continue; } foreach (KeyValuePair 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 list = (List)_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 list = _uiChildrenField?.GetValue(__instance) as List; 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(val2, val2.parent); ((Object)val4).name = $"Inventory Spot {j + 1}"; InventorySpot component = ((Component)val4).GetComponent(); component.inventorySpotIndex = j; Transform obj = val4.Find("Numbers"); TextMeshProUGUI val5 = ((obj != null) ? ((Component)obj).GetComponent() : 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(); } if ((Object)(object)val == (Object)null) { return; } ItemEquippable component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { return; } List 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)list).FirstOrDefault((Func)((PlayerAvatar p) => SemiFunc.PlayerGetSteamID(p) == sid)); if ((Object)(object)val3 != (Object)null) { num = val3.photonView.ViewID; } } component.RequestEquip(slot, num); } EquipTracker.Erase(sid, slot); } }