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 ImprovedBeltBag v1.0.0
plugins/Iron.ImprovedBeltBag.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using ImprovedBeltBag.Networking; using ImprovedBeltBag.Patches; using ImprovedBeltBag.Utils; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Iron.ImprovedBeltBag")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ImprovedBeltBag")] [assembly: AssemblyTitle("Iron.ImprovedBeltBag")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ImprovedBeltBag { internal static class ItemClassifier { public static bool IsShotgun(GrabbableObject g) { if (!HasClass(g, "ShotgunItem")) { return NameIs(g, "shotgun"); } return true; } public static bool IsKnife(GrabbableObject g) { if (!HasClass(g, "KnifeItem")) { return NameContains(g, "knife"); } return true; } public static bool IsSign(GrabbableObject g) { string text = Name(g); if (text == "stop sign" || text == "yield sign") { return true; } if (HasClass(g, "Shovel") && (Object)(object)g.itemProperties != (Object)null) { return g.itemProperties.isScrap; } return false; } private static string Name(GrabbableObject g) { if (!((Object)(object)g.itemProperties != (Object)null) || g.itemProperties.itemName == null) { return ""; } return g.itemProperties.itemName.Trim().ToLowerInvariant(); } private static bool NameIs(GrabbableObject g, string s) { return Name(g) == s; } private static bool NameContains(GrabbableObject g, string s) { return Name(g).Contains(s); } private static bool HasClass(GrabbableObject g, string simpleName) { Type type = ((object)g).GetType(); while (type != null && type != typeof(GrabbableObject)) { if (type.Name == simpleName) { return true; } type = type.BaseType; } return false; } } [BepInPlugin("Iron.ImprovedBeltBag", "ImprovedBeltBag", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PLUGIN_GUID = "Iron.ImprovedBeltBag"; public const string PLUGIN_NAME = "ImprovedBeltBag"; public const string PLUGIN_VERSION = "1.0.0"; private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; try { PluginConfig.Init(((BaseUnityPlugin)this).Config); _harmony = new Harmony("Iron.ImprovedBeltBag"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"ImprovedBeltBag v1.0.0 loaded."); } catch (Exception arg) { Log.LogError((object)$"Failed to initialize; the mod is inactive: {arg}"); } } } internal static class PluginConfig { internal interface ICategoryConfig { string CategoryName { get; } bool Allow { get; } int Limit { get; } } internal sealed class StaticCategoryConfig : ICategoryConfig { public string CategoryName { get; } public bool Allow { get; } public int Limit { get; } public StaticCategoryConfig(string name, bool allow, int limit) { CategoryName = name; Allow = allow; Limit = limit; } } internal sealed class CategoryConfig : ICategoryConfig { private readonly ConfigEntry<bool> _allow; private readonly ConfigEntry<int> _limit; public string CategoryName { get; } public bool Allow => _allow.Value; public int Limit => _limit.Value; public CategoryConfig(ConfigFile cfg, string name, bool allowDefault, string desc) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown CategoryName = name; _allow = cfg.Bind<bool>("Category." + name, "Allow", allowDefault, "Allow storing " + name + ". " + desc); _limit = cfg.Bind<int>("Category." + name, "Max Amount", -1, new ConfigDescription("Max number of " + name + " at once (-1 = only limited by Capacity).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 100), Array.Empty<object>())); } } internal const string ToolsCategory = "Tools"; internal const string ShotgunCategory = "Shotgun"; internal const string KnifeCategory = "Knife"; internal const string SignsCategory = "Signs"; internal const string OneHandedScrapCategory = "One Handed Scrap"; internal const string TwoHandedScrapCategory = "Two Handed Scrap"; internal const string DenyCategory = "Deny"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> Capacity; internal static ConfigEntry<bool> ResizeSlotUI; internal static ConfigEntry<int> SlotsPerRow; internal static ConfigEntry<string> ItemCategories; internal static StringDictionary Associations = new StringDictionary(); internal static readonly Dictionary<string, ICategoryConfig> CategoryConfigs = new Dictionary<string, ICategoryConfig>(); internal static ConfigEntry<bool> WeightEnabled; internal static ConfigEntry<float> WeightMultiplier; internal static ConfigEntry<float> GrabRange; internal static ConfigEntry<bool> Tooltip; internal static ConfigEntry<bool> DropAll; internal static ConfigEntry<bool> EnforceCapacity; internal static ConfigEntry<bool> EnforceCategory; internal static ConfigEntry<bool> EnforceRange; internal static void Init(ConfigFile cfg) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown Enabled = cfg.Bind<bool>("General", "Enabled", true, "Master switch for the whole mod."); Capacity = cfg.Bind<int>("Slots", "Capacity", 15, new ConfigDescription("How many items the bag can hold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ResizeSlotUI = cfg.Bind<bool>("Slots", "Resize Inventory UI", true, "Rebuild the belt bag inventory grid so the number of visible slot squares matches Capacity."); SlotsPerRow = cfg.Bind<int>("Slots", "Slots Per Row", 5, new ConfigDescription("How many slot squares per row when the UI is rebuilt.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); ItemCategories = cfg.Bind<string>("Items", "Per-Item Overrides", "Body: Deny, Apparatus: Deny", "Comma-separated 'ItemName: CategoryName' overrides, e.g. 'Zap gun: Deny, Gold bar: Scrap'. Any category name you use here is auto-created below with Allow/Max settings."); CategoryConfigs["Tools"] = new CategoryConfig(cfg, "Tools", allowDefault: true, "Non-scrap tools/equipment: flashlight, walkie-talkie, zap gun, extension ladder, shovel, etc."); CategoryConfigs["Shotgun"] = new CategoryConfig(cfg, "Shotgun", allowDefault: true, "The Shotgun."); CategoryConfigs["Knife"] = new CategoryConfig(cfg, "Knife", allowDefault: true, "The Kitchen knife."); CategoryConfigs["Signs"] = new CategoryConfig(cfg, "Signs", allowDefault: true, "Stop sign / Yield sign."); CategoryConfigs["One Handed Scrap"] = new CategoryConfig(cfg, "One Handed Scrap", allowDefault: false, "Generic ONE-handed sellable scrap / metal loot (not knife/signs). OFF by default. Use 'Max Amount' to cap how many one-handed junk items fit."); CategoryConfigs["Two Handed Scrap"] = new CategoryConfig(cfg, "Two Handed Scrap", allowDefault: false, "Generic TWO-handed sellable scrap / large metal loot (not shotgun). OFF by default. Use 'Max Amount' to cap how many two-handed junk items fit."); CategoryConfigs["Deny"] = new StaticCategoryConfig("Deny", allow: false, 0); RebuildAssociations(); ItemCategories.SettingChanged += delegate { RebuildAssociations(); }; WeightEnabled = cfg.Bind<bool>("Weight", "Enabled", true, "Make the bag weigh you down by the weight of its contents (vanilla bags are weightless)."); WeightMultiplier = cfg.Bind<float>("Weight", "Multiplier", 1f, new ConfigDescription("Fraction of each stored item's weight that is applied while you carry the bag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); GrabRange = cfg.Bind<float>("Misc", "Grab Range", 4f, new ConfigDescription("Max range to grab items into the bag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); Tooltip = cfg.Bind<bool>("Misc", "Tooltips", true, "Show a HUD tip when an item can't be stored (full / not allowed / limit reached)."); DropAll = cfg.Bind<bool>("Misc", "Empty Bag Action", true, "Right-interact while holding the bag empties it onto the ground."); EnforceCapacity = cfg.Bind<bool>("Host", "Enforce Capacity", true, "Server-side capacity check (prevents clients exceeding the host's Capacity)."); EnforceCategory = cfg.Bind<bool>("Host", "Enforce Restrictions", true, "Server-side item-restriction check (prevents clients bagging items the host disallows)."); EnforceRange = cfg.Bind<bool>("Host", "Enforce Range", true, "Server-side grab-range check."); ((Dictionary<ConfigDefinition, string>)(typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(cfg)))?.Clear(); cfg.Save(); } private static void RebuildAssociations() { StringDictionary stringDictionary = new StringDictionary(); string[] array = ItemCategories.Value.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0) { string[] array2 = text.Split(':'); if (array2.Length != 2) { Plugin.Log.LogError((object)("Per-Item Overrides: malformed entry '" + text + "'")); } else { stringDictionary[array2[0].Trim()] = array2[1].Trim(); } } } Associations = stringDictionary; foreach (string value in stringDictionary.Values) { if (!CategoryConfigs.ContainsKey(value)) { CategoryConfigs[value] = new CategoryConfig(((BaseUnityPlugin)Plugin.Instance).Config, value, allowDefault: true, "Custom category."); } } } internal static ICategoryConfig CategoryOf(GrabbableObject grabbable) { string itemName = grabbable.itemProperties.itemName; if (itemName != null && Associations.ContainsKey(itemName) && CategoryConfigs.TryGetValue(Associations[itemName], out var value)) { return value; } if (ItemClassifier.IsShotgun(grabbable)) { return CategoryConfigs["Shotgun"]; } if (ItemClassifier.IsKnife(grabbable)) { return CategoryConfigs["Knife"]; } if (ItemClassifier.IsSign(grabbable)) { return CategoryConfigs["Signs"]; } if (!grabbable.itemProperties.isScrap) { return CategoryConfigs["Tools"]; } if (!grabbable.itemProperties.twoHanded) { return CategoryConfigs["One Handed Scrap"]; } return CategoryConfigs["Two Handed Scrap"]; } } } namespace ImprovedBeltBag.Utils { internal static class NgoUtils { internal static bool IsRpcServerStage(this NetworkBehaviour self) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 NetworkManager networkManager = self.NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return false; } if ((int)self.__rpc_exec_stage != 1) { return false; } if (!networkManager.IsServer) { return networkManager.IsHost; } return true; } } } namespace ImprovedBeltBag.Patches { [HarmonyPatch] internal static class BagUiPatch { private static string _iconPath; private static bool _captured; private static Vector2 _cellSize; private static float _xStep; private static float _yStep; private static Vector2 _center; [HarmonyPrefix] [HarmonyPatch(typeof(BeltBagInventoryUI), "FillSlots")] private static void BeforeFillSlots(BeltBagInventoryUI __instance) { if (!BeltBagPatch.Enabled || !PluginConfig.Enabled.Value || !PluginConfig.ResizeSlotUI.Value) { return; } try { EnsureSlots(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"Belt bag UI resize failed (harmless): {arg}"); } } private static void EnsureSlots(BeltBagInventoryUI ui) { GameObject[] inventorySlots = ui.inventorySlots; Image[] inventorySlotIcons = ui.inventorySlotIcons; if (inventorySlots == null || inventorySlots.Length == 0 || inventorySlotIcons == null || inventorySlotIcons.Length == 0) { return; } int num = Mathf.Clamp(PluginConfig.Capacity.Value, 1, 100); int num2 = inventorySlots.Length; if (num2 == num) { return; } GameObject val = inventorySlots[0]; Transform parent = val.transform.parent; if (_iconPath == null) { _iconPath = RelativePath(inventorySlots[0].transform, ((Component)inventorySlotIcons[0]).transform); } CaptureMetrics(inventorySlots); DisableLayoutGroups(parent); GameObject[] array = (GameObject[])(object)new GameObject[num]; Image[] array2 = (Image[])(object)new Image[num]; for (int i = 0; i < num; i++) { GameObject val2; Image val3; if (i < num2 && (Object)(object)inventorySlots[i] != (Object)null) { val2 = inventorySlots[i]; val3 = inventorySlotIcons[i]; } else { val2 = Object.Instantiate<GameObject>(val, parent); ((Object)val2).name = $"BeltBagSlot({i})"; val3 = ResolveIcon(val2); RewireClick(ui, val2, i); } val2.SetActive(true); if ((Object)(object)val3 != (Object)null) { ((Behaviour)val3).enabled = false; } array[i] = val2; array2[i] = val3; } for (int j = num; j < num2; j++) { if ((Object)(object)inventorySlots[j] != (Object)null) { inventorySlots[j].SetActive(false); } } ui.inventorySlots = array; ui.inventorySlotIcons = array2; LayoutSlots(array); } private static void CaptureMetrics(GameObject[] slots) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (_captured) { return; } RectTransform component = slots[0].GetComponent<RectTransform>(); Rect rect = component.rect; _cellSize = ((Rect)(ref rect)).size; float y = component.anchoredPosition.y; int num = 0; float num2 = float.MaxValue; float num3 = float.MinValue; float num4 = float.MaxValue; float num5 = float.MinValue; RectTransform val = null; RectTransform val2 = null; for (int i = 0; i < slots.Length; i++) { RectTransform component2 = slots[i].GetComponent<RectTransform>(); Vector2 anchoredPosition = component2.anchoredPosition; if (Mathf.Abs(anchoredPosition.y - y) < 1f) { num++; if ((Object)(object)val == (Object)null && anchoredPosition.x > component.anchoredPosition.x + 1f) { val = component2; } } else if ((Object)(object)val2 == (Object)null) { val2 = component2; } num2 = Mathf.Min(num2, anchoredPosition.x); num3 = Mathf.Max(num3, anchoredPosition.x); num4 = Mathf.Min(num4, anchoredPosition.y); num5 = Mathf.Max(num5, anchoredPosition.y); } _xStep = (((Object)(object)val != (Object)null) ? Mathf.Abs(val.anchoredPosition.x - component.anchoredPosition.x) : Mathf.Max(1f, _cellSize.x * 1.15f)); _yStep = (((Object)(object)val2 != (Object)null) ? Mathf.Abs(val2.anchoredPosition.y - y) : Mathf.Max(1f, _cellSize.y * 1.15f)); _center = new Vector2((num2 + num3) * 0.5f, (num4 + num5) * 0.5f); _captured = true; } private static void LayoutSlots(GameObject[] slots) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (!_captured) { return; } int num = slots.Length; int num2 = Mathf.Max(1, PluginConfig.SlotsPerRow.Value); float num3 = (float)(Mathf.CeilToInt((float)num / (float)num2) - 1) * _yStep; for (int i = 0; i < num; i++) { int num4 = i / num2; int num5 = i % num2; float num6 = (float)(Mathf.Min(num2, num - num4 * num2) - 1) * _xStep; float num7 = _center.x - num6 * 0.5f + (float)num5 * _xStep; float num8 = _center.y + num3 * 0.5f - (float)num4 * _yStep; RectTransform component = slots[i].GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(num7, num8); if (((Vector2)(ref _cellSize)).sqrMagnitude > 0.01f) { component.sizeDelta = _cellSize; } } } } private static void DisableLayoutGroups(Transform container) { LayoutGroup[] components = ((Component)container).GetComponents<LayoutGroup>(); for (int i = 0; i < components.Length; i++) { ((Behaviour)components[i]).enabled = false; } ContentSizeFitter[] components2 = ((Component)container).GetComponents<ContentSizeFitter>(); for (int i = 0; i < components2.Length; i++) { ((Behaviour)components2[i]).enabled = false; } } private static Image ResolveIcon(GameObject slotClone) { if (string.IsNullOrEmpty(_iconPath)) { return slotClone.GetComponent<Image>(); } Transform val = slotClone.transform.Find(_iconPath); if (!((Object)(object)val != (Object)null)) { return slotClone.GetComponentInChildren<Image>(true); } return ((Component)val).GetComponent<Image>(); } private static void RewireClick(BeltBagInventoryUI ui, GameObject slot, int index) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown Button componentInChildren = slot.GetComponentInChildren<Button>(true); if (!((Object)(object)componentInChildren == (Object)null)) { ((UnityEventBase)componentInChildren.onClick).RemoveAllListeners(); ((UnityEvent)componentInChildren.onClick).AddListener((UnityAction)delegate { ui.ClickInventorySlot(index); }); } } private static string RelativePath(Transform root, Transform child) { if ((Object)(object)child == (Object)(object)root || (Object)(object)child == (Object)null) { return ""; } StringBuilder stringBuilder = new StringBuilder(); Transform val = child; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { if (stringBuilder.Length > 0) { stringBuilder.Insert(0, '/'); } stringBuilder.Insert(0, ((Object)val).name); val = val.parent; } return stringBuilder.ToString(); } } [HarmonyPatch] internal static class BeltBagPatch { private sealed class Counter { public int Count; } internal static bool Enabled; private const int ManeaterItemIdA = 123984; private const int ManeaterItemIdB = 819501; private static readonly ConditionalWeakTable<BeltBagItem, ConditionalWeakTable<PluginConfig.ICategoryConfig, Counter>> Memory = new ConditionalWeakTable<BeltBagItem, ConditionalWeakTable<PluginConfig.ICategoryConfig, Counter>>(); [HarmonyPrefix] [HarmonyPatch(typeof(BeltBagItem), "ItemInteractLeftRight")] private static bool ItemInteractLeftRight_Prefix(BeltBagItem __instance, bool right) { if (!Enabled || !PluginConfig.Enabled.Value) { return true; } try { if (right) { TryDumpItems(__instance); } else { TryGrabItem(__instance); } } catch (Exception arg) { Plugin.Log.LogError((object)$"ItemInteractLeftRight_Prefix error: {arg}"); } return false; } private static void TryGrabItem(BeltBagItem bag) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB playerHeldBy = ((GrabbableObject)bag).playerHeldBy; if ((Object)(object)playerHeldBy == (Object)null || (Object)(object)playerHeldBy.currentlyHeldObjectServer != (Object)(object)bag || bag.tryingAddToBag) { return; } if (bag.objectsInBag.Count >= PluginConfig.Capacity.Value) { Tip("This bag is full!"); return; } Transform transform = ((Component)playerHeldBy.gameplayCamera).transform; RaycastHit val = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val, PluginConfig.GrabRange.Value, playerHeldBy.interactableObjectsMask) || ((Component)((RaycastHit)(ref val)).collider).gameObject.layer == 8 || !((Component)((RaycastHit)(ref val)).collider).CompareTag("PhysicsProp")) { return; } GrabbableObject component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<GrabbableObject>(); if (CanBePutInBag(bag, component)) { if (CheckBagFilters(bag, component, out var limited, out var disallowed)) { bag.TryAddObjectToBag(component); } else if (disallowed) { Tip("Cannot store " + component.itemProperties.itemName + " in the bag!"); } else if (limited) { Tip("Cannot store any more " + PluginConfig.CategoryOf(component).CategoryName + " in the bag!"); } } } private static void TryDumpItems(BeltBagItem bag) { if (PluginConfig.DropAll.Value && !((Object)(object)((GrabbableObject)bag).playerHeldBy == (Object)null) && !((Object)(object)((GrabbableObject)bag).playerHeldBy.currentlyHeldObjectServer != (Object)(object)bag)) { ((MonoBehaviour)bag).StartCoroutine(EmptyBag(bag)); } } private static IEnumerator EmptyBag(BeltBagItem bag) { while (bag.objectsInBag.Count > 0) { bag.RemoveObjectFromBag(0); yield return (object)new WaitForEndOfFrame(); } } private static bool CanBePutInBag(BeltBagItem bag, GrabbableObject g) { if ((Object)(object)g != (Object)null && (Object)(object)g != (Object)(object)bag && !g.isHeld && !g.isHeldByEnemy && g.itemProperties.itemId != 123984) { return g.itemProperties.itemId != 819501; } return false; } private static bool CheckBagFilters(BeltBagItem bag, GrabbableObject g, out bool limited, out bool disallowed) { limited = false; PluginConfig.ICategoryConfig categoryConfig = PluginConfig.CategoryOf(g); disallowed = !categoryConfig.Allow; if (disallowed) { return false; } int limit = categoryConfig.Limit; if (limit < 0) { return true; } if (limit == 0) { limited = true; return false; } if (CountInCategory(bag, categoryConfig) >= limit) { limited = true; return false; } return true; } private static void Tip(string message) { if (PluginConfig.Tooltip.Value && (Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Belt bag", message, false, false, "LC_Tip1"); } } private static int CountInCategory(BeltBagItem bag, PluginConfig.ICategoryConfig cat) { if (!Memory.GetOrCreateValue(bag).TryGetValue(cat, out var value)) { return 0; } return value.Count; } [HarmonyPostfix] [HarmonyPatch(typeof(BeltBagItem), "PutObjectInBagLocalClient")] private static void OnPutInBag(BeltBagItem __instance, GrabbableObject gObject, ref bool __state) { if (!__state) { Memory.GetOrCreateValue(__instance).GetOrCreateValue(PluginConfig.CategoryOf(gObject)).Count++; } } [HarmonyPrefix] [HarmonyPatch(typeof(BeltBagItem), "PutObjectInBagLocalClient")] private static void BeforePutInBag(BeltBagItem __instance, GrabbableObject gObject, ref bool __state) { __state = __instance.objectsInBag.Contains(gObject); } [HarmonyPostfix] [HarmonyPatch(typeof(BeltBagItem), "RemoveFromBagLocalClient")] [HarmonyPatch(typeof(BeltBagItem), "RemoveFromBagLocalClientNonElevatorParent")] private static void OnRemoveFromBag(BeltBagItem __instance, NetworkObjectReference objectRef) { ConditionalWeakTable<PluginConfig.ICategoryConfig, Counter> orCreateValue = Memory.GetOrCreateValue(__instance); NetworkObject val = default(NetworkObject); GrabbableObject grabbable = default(GrabbableObject); if (((NetworkObjectReference)(ref objectRef)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref grabbable)) { Counter orCreateValue2 = orCreateValue.GetOrCreateValue(PluginConfig.CategoryOf(grabbable)); if (orCreateValue2.Count > 0) { orCreateValue2.Count--; } } if (__instance.objectsInBag.Count == 0) { orCreateValue.Clear(); } } [HarmonyPrefix] [HarmonyPatch(typeof(BeltBagItem), "TryAddObjectToBagServerRpc")] private static bool EnforceOnServer(BeltBagItem __instance, NetworkObjectReference netObjectRef, int playerWhoAdded) { //IL_00c5: 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) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (!Enabled || !PluginConfig.Enabled.Value) { return true; } if (!((NetworkBehaviour)(object)__instance).IsRpcServerStage()) { return true; } NetworkObject val = default(NetworkObject); if (!((NetworkObjectReference)(ref netObjectRef)).TryGet(ref val, (NetworkManager)null)) { return true; } GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>(); if (!CanBePutInBag(__instance, component)) { __instance.CancelAddObjectToBagClientRpc(playerWhoAdded); return false; } if (PluginConfig.EnforceCapacity.Value && __instance.objectsInBag.Count >= PluginConfig.Capacity.Value) { __instance.CancelAddObjectToBagClientRpc(playerWhoAdded); return false; } if (PluginConfig.EnforceCategory.Value && !CheckBagFilters(__instance, component, out var _, out var _)) { __instance.CancelAddObjectToBagClientRpc(playerWhoAdded); return false; } if (PluginConfig.EnforceRange.Value) { Vector3 val2 = (((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null) ? ((Component)((GrabbableObject)__instance).playerHeldBy.gameplayCamera).transform.position : Vector3.positiveInfinity); if (Vector3.Distance(((Component)component).transform.position, val2) > PluginConfig.GrabRange.Value + 1f) { __instance.CancelAddObjectToBagClientRpc(playerWhoAdded); return false; } } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(BeltBagItem), "CancelAddObjectToBagClientRpc")] private static void OnServerRefusal(int playerWhoAdded) { if (!((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)StartOfRound.Instance.allPlayerScripts[playerWhoAdded] != (Object)(object)GameNetworkManager.Instance.localPlayerController)) { Tip("The host refused that item."); } } } [HarmonyPatch] internal static class NetworkPatches { [HarmonyPostfix] [HarmonyPatch(typeof(NetworkManager), "Initialize")] private static void AfterNetworkInitialize() { NamedMessages.Register(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "SetInstanceValuesBackToDefault")] private static void OnNetworkTearDown() { NamedMessages.Unregister(); } [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "Start")] private static void OnLobbyStart(StartOfRound __instance) { BeltBagPatch.Enabled = ((NetworkBehaviour)__instance).IsServer; } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] private static void OnClientConnected(StartOfRound __instance, ulong __0) { if (((NetworkBehaviour)__instance).IsServer) { NamedMessages.SendHostPresent(new ulong[1] { __0 }); } } [HarmonyPrefix] [HarmonyPatch(typeof(MenuManager), "Start")] private static void OnMainMenu() { BeltBagPatch.Enabled = false; } } [HarmonyPatch] internal static class WeightPatch { private sealed class State { public PlayerControllerB Player; public float Amount; } private static readonly ConditionalWeakTable<BeltBagItem, State> Applied = new ConditionalWeakTable<BeltBagItem, State>(); [HarmonyPostfix] [HarmonyPatch(typeof(BeltBagItem), "LateUpdate")] private static void AfterLateUpdate(BeltBagItem __instance) { Reconcile(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(BeltBagItem), "OnDisable")] private static void AfterOnDisable(BeltBagItem __instance) { Remove(__instance); } private static float DesiredWeight(BeltBagItem bag) { if (!BeltBagPatch.Enabled || !PluginConfig.Enabled.Value || !PluginConfig.WeightEnabled.Value) { return 0f; } if ((Object)(object)((GrabbableObject)bag).playerHeldBy == (Object)null || bag.objectsInBag == null) { return 0f; } float value = PluginConfig.WeightMultiplier.Value; float num = 0f; foreach (GrabbableObject item in bag.objectsInBag) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item.itemProperties == (Object)null)) { num += Mathf.Clamp(item.itemProperties.weight - 1f, 0f, 10f); } } return num * value; } private static void Reconcile(BeltBagItem bag) { if (!((Object)(object)bag == (Object)null)) { State orCreateValue = Applied.GetOrCreateValue(bag); PlayerControllerB val = ((BeltBagPatch.Enabled && PluginConfig.Enabled.Value && PluginConfig.WeightEnabled.Value) ? ((GrabbableObject)bag).playerHeldBy : null); float num = (((Object)(object)val != (Object)null) ? DesiredWeight(bag) : 0f); if ((Object)(object)orCreateValue.Player != (Object)null && ((Object)(object)orCreateValue.Player != (Object)(object)val || !Mathf.Approximately(orCreateValue.Amount, num))) { orCreateValue.Player.carryWeight = Mathf.Max(1f, orCreateValue.Player.carryWeight - orCreateValue.Amount); orCreateValue.Player = null; orCreateValue.Amount = 0f; } if ((Object)(object)val != (Object)null && num > 0f && (Object)(object)orCreateValue.Player == (Object)null) { val.carryWeight += num; orCreateValue.Player = val; orCreateValue.Amount = num; } } } private static void Remove(BeltBagItem bag) { if (!((Object)(object)bag == (Object)null) && Applied.TryGetValue(bag, out var value) && (Object)(object)value.Player != (Object)null) { value.Player.carryWeight = Mathf.Max(1f, value.Player.carryWeight - value.Amount); value.Player = null; value.Amount = 0f; } } } } namespace ImprovedBeltBag.Networking { internal static class NamedMessages { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnHostPresent; public static HandleNamedMessageDelegate <1>__OnFixBags; } private static readonly string Base = "Iron.ImprovedBeltBag"; private static readonly string HostPresentMsg = Base + "|HostPresent"; private static readonly string FixBagsMsg = Base + "|FixBags"; internal static void Register() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; CustomMessagingManager val = ((singleton != null) ? singleton.CustomMessagingManager : null); if (val != null) { string hostPresentMsg = HostPresentMsg; object obj = <>O.<0>__OnHostPresent; if (obj == null) { HandleNamedMessageDelegate val2 = OnHostPresent; <>O.<0>__OnHostPresent = val2; obj = (object)val2; } val.RegisterNamedMessageHandler(hostPresentMsg, (HandleNamedMessageDelegate)obj); string fixBagsMsg = FixBagsMsg; object obj2 = <>O.<1>__OnFixBags; if (obj2 == null) { HandleNamedMessageDelegate val3 = OnFixBags; <>O.<1>__OnFixBags = val3; obj2 = (object)val3; } val.RegisterNamedMessageHandler(fixBagsMsg, (HandleNamedMessageDelegate)obj2); } } internal static void Unregister() { NetworkManager singleton = NetworkManager.Singleton; CustomMessagingManager val = ((singleton != null) ? singleton.CustomMessagingManager : null); if (val != null) { val.UnregisterNamedMessageHandler(HostPresentMsg); val.UnregisterNamedMessageHandler(FixBagsMsg); } } internal static void SendHostPresent(IReadOnlyList<ulong> targets = null) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && singleton.IsServer && singleton.CustomMessagingManager != null) { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1); if (targets == null) { singleton.CustomMessagingManager.SendNamedMessageToAll(HostPresentMsg, val, (NetworkDelivery)3); } else { singleton.CustomMessagingManager.SendNamedMessage(HostPresentMsg, targets, val, (NetworkDelivery)3); } } } private static void OnHostPresent(ulong senderId, FastBufferReader reader) { if (senderId == 0L) { BeltBagPatch.Enabled = true; if (PluginConfig.Enabled != null && Plugin.Log != null) { Plugin.Log.LogInfo((object)"Host has ImprovedBeltBag — bag tweaks enabled (client)."); } } } internal static void SendFixBags() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && singleton.IsServer && singleton.CustomMessagingManager != null) { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1); singleton.CustomMessagingManager.SendNamedMessageToAll(FixBagsMsg, val, (NetworkDelivery)3); } } private static void OnFixBags(ulong senderId, FastBufferReader reader) { if (senderId == 0L && !((Object)(object)StartOfRound.Instance == (Object)null)) { BeltBagItem[] array = Object.FindObjectsByType<BeltBagItem>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (BeltBagItem obj in array) { obj.tryingAddToBag = false; obj.tryingCheckBag = false; } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }