Decompiled source of DrifterBossGrab v1.6.10

plugins/com.pwdcat.DrifterBossGrab.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DrifterBossGrabMod.Interfaces;
using DrifterBossGrabMod.Networking;
using DrifterBossGrabMod.Patches;
using DrifterBossGrabMod.UI;
using EntityStates;
using EntityStates.CaptainSupplyDrop;
using EntityStates.Drifter;
using EntityStates.Drifter.Bag;
using EntityStates.SurvivorPod;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.HudOverlay;
using RoR2.Networking;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("com.pwdcat.DrifterBossGrab")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.6.10.0")]
[assembly: AssemblyInformationalVersion("1.6.10")]
[assembly: AssemblyProduct("com.pwdcat.DrifterBossGrab")]
[assembly: AssemblyTitle("DrifterBossGrabMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.10.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace DrifterBossGrabMod
{
	public static class ConfigChangeNotifier
	{
		private static readonly List<IConfigObserver> observers = new List<IConfigObserver>();

		private static readonly EventHandler configChangedHandler = OnConfigChanged;

		public static void AddObserver(IConfigObserver observer)
		{
			observers.Add(observer);
		}

		public static void RemoveObserver(IConfigObserver observer)
		{
			observers.Remove(observer);
		}

		private static void OnConfigChanged(object sender, EventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ConfigEntryBase val = (ConfigEntryBase)sender;
			NotifyObservers(val.Definition.Key, val.BoxedValue);
		}

		private static void NotifyObservers(string key, object value)
		{
			foreach (IConfigObserver observer in observers)
			{
				observer.OnConfigChanged(key, value);
			}
		}

		public static void Init()
		{
			PluginConfig.Instance.SearchRangeMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BreakoutTimeMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ForwardVelocityMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.UpwardVelocityMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableBossGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableNPCGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ProjectileGrabbingMode.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MaxSmacks.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MassMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableDebugLogs.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BodyBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.RecoveryObjectBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.GrabbableComponentTypes.SettingChanged += configChangedHandler;
			PluginConfig.Instance.GrabbableKeywordBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableComponentAnalysisLogs.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableAutoGrab.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedBosses.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedNPCs.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedEnvironmentObjects.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistenceBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BottomlessBagBaseCapacity.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableMouseWheelScrolling.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ScrollUpKeybind.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ScrollDownKeybind.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CarouselSpacing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CarouselSideScale.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CarouselSideOpacity.SettingChanged += configChangedHandler;
		}

		public static void Cleanup()
		{
			PluginConfig.Instance.SearchRangeMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BreakoutTimeMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ForwardVelocityMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.UpwardVelocityMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableBossGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableNPCGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ProjectileGrabbingMode.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MaxSmacks.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MassMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableDebugLogs.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BodyBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.RecoveryObjectBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.GrabbableComponentTypes.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.GrabbableKeywordBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableComponentAnalysisLogs.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableAutoGrab.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedBosses.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedNPCs.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedEnvironmentObjects.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistenceBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BottomlessBagBaseCapacity.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableMouseWheelScrolling.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ScrollUpKeybind.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ScrollDownKeybind.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CarouselSpacing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CarouselSideScale.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CarouselSideOpacity.SettingChanged -= configChangedHandler;
		}
	}
	public class ConfigurationComposite : IConfigurable
	{
		private readonly List<IConfigurable> _components = new List<IConfigurable>();

		public void AddComponent(IConfigurable component)
		{
			if (component == null)
			{
				throw new ArgumentNullException("component");
			}
			_components.Add(component);
		}

		public bool RemoveComponent(IConfigurable component)
		{
			return _components.Remove(component);
		}

		public IReadOnlyCollection<IConfigurable> GetComponents()
		{
			return _components.AsReadOnly();
		}

		public void Initialize()
		{
			foreach (IConfigurable component in _components)
			{
				try
				{
					component.Initialize();
				}
				catch (Exception ex)
				{
					Log.Error("Failed to initialize component " + component.GetType().Name + ": " + ex.Message);
				}
			}
		}

		public void Cleanup()
		{
			foreach (IConfigurable component in _components)
			{
				try
				{
					component.Cleanup();
				}
				catch (Exception ex)
				{
					Log.Error("Failed to cleanup component " + component.GetType().Name + ": " + ex.Message);
				}
			}
			_components.Clear();
		}
	}
	public enum ProjectileGrabbingMode
	{
		None,
		SurvivorOnly,
		AllProjectiles
	}
	public interface ICachedValue<T>
	{
		T Value { get; }

		void Invalidate();
	}
	public class LazyCachedValue<T> : ICachedValue<T>
	{
		private readonly Func<T> _factory;

		private T? _value;

		private bool _isValid;

		private readonly object _lock = new object();

		public T Value
		{
			get
			{
				lock (_lock)
				{
					if (!_isValid)
					{
						_value = _factory();
						_isValid = true;
					}
					return _value;
				}
			}
		}

		public void Invalidate()
		{
			lock (_lock)
			{
				_isValid = false;
				_value = default(T);
			}
		}

		public LazyCachedValue(Func<T> factory)
		{
			_factory = factory ?? throw new ArgumentNullException("factory");
		}
	}
	public class PluginConfig
	{
		private static PluginConfig _instance;

		internal ICachedValue<HashSet<string>> _blacklistCache;

		internal ICachedValue<HashSet<string>> _blacklistCacheWithClones;

		internal ICachedValue<HashSet<string>> _recoveryBlacklistCache;

		internal ICachedValue<HashSet<string>> _recoveryBlacklistCacheWithClones;

		internal ICachedValue<HashSet<string>> _grabbableComponentTypesCache;

		internal ICachedValue<HashSet<string>> _grabbableKeywordBlacklistCache;

		private readonly List<IGrabbingStrategy> _grabbingStrategies = new List<IGrabbingStrategy>
		{
			new BossGrabbingStrategy(),
			new NPCGrabbingStrategy(),
			new EnvironmentGrabbingStrategy()
		};

		public static PluginConfig Instance => _instance ?? (_instance = new PluginConfig());

		public ConfigEntry<float> SearchRangeMultiplier { get; private set; }

		public ConfigEntry<float> BreakoutTimeMultiplier { get; private set; }

		public ConfigEntry<float> ForwardVelocityMultiplier { get; private set; }

		public ConfigEntry<float> UpwardVelocityMultiplier { get; private set; }

		public ConfigEntry<bool> EnableBossGrabbing { get; private set; }

		public ConfigEntry<bool> EnableNPCGrabbing { get; private set; }

		public ConfigEntry<bool> EnableEnvironmentGrabbing { get; private set; }

		public ConfigEntry<bool> EnableLockedObjectGrabbing { get; private set; }

		public ConfigEntry<ProjectileGrabbingMode> ProjectileGrabbingMode { get; private set; }

		public ConfigEntry<int> MaxSmacks { get; private set; }

		public ConfigEntry<string> MassMultiplier { get; private set; }

		public ConfigEntry<bool> EnableDebugLogs { get; private set; }

		public ConfigEntry<string> BodyBlacklist { get; private set; }

		public ConfigEntry<string> RecoveryObjectBlacklist { get; private set; }

		public ConfigEntry<string> GrabbableComponentTypes { get; private set; }

		public ConfigEntry<string> GrabbableKeywordBlacklist { get; private set; }

		public ConfigEntry<bool> EnableConfigSync { get; private set; }

		public ConfigEntry<bool> EnableComponentAnalysisLogs { get; private set; }

		public ConfigEntry<bool> EnableObjectPersistence { get; private set; }

		public ConfigEntry<bool> EnableAutoGrab { get; private set; }

		public ConfigEntry<bool> PersistBaggedBosses { get; private set; }

		public ConfigEntry<bool> PersistBaggedNPCs { get; private set; }

		public ConfigEntry<bool> PersistBaggedEnvironmentObjects { get; private set; }

		public ConfigEntry<string> PersistenceBlacklist { get; private set; }

		public ConfigEntry<float> AutoGrabDelay { get; private set; }

		public ConfigEntry<bool> BottomlessBagEnabled { get; private set; }

		public ConfigEntry<int> BottomlessBagBaseCapacity { get; private set; }

		public ConfigEntry<bool> EnableStockRefreshClamping { get; private set; }

		public ConfigEntry<float> CycleCooldown { get; private set; }

		public ConfigEntry<bool> EnableMouseWheelScrolling { get; private set; }

		public ConfigEntry<bool> InverseMouseWheelScrolling { get; private set; }

		public ConfigEntry<KeyboardShortcut> ScrollUpKeybind { get; private set; }

		public ConfigEntry<KeyboardShortcut> ScrollDownKeybind { get; private set; }

		public ConfigEntry<float> CarouselSpacing { get; private set; }

		public ConfigEntry<float> CarouselCenterOffsetX { get; private set; }

		public ConfigEntry<float> CarouselCenterOffsetY { get; private set; }

		public ConfigEntry<float> CarouselSideOffsetX { get; private set; }

		public ConfigEntry<float> CarouselSideOffsetY { get; private set; }

		public ConfigEntry<float> CarouselSideScale { get; private set; }

		public ConfigEntry<float> CarouselSideOpacity { get; private set; }

		public ConfigEntry<float> CarouselAnimationDuration { get; private set; }

		public ConfigEntry<bool> BagUIShowIcon { get; private set; }

		public ConfigEntry<bool> BagUIShowWeight { get; private set; }

		public ConfigEntry<bool> BagUIShowName { get; private set; }

		public ConfigEntry<bool> BagUIShowHealthBar { get; private set; }

		public ConfigEntry<bool> UseNewWeightIcon { get; private set; }

		public ConfigEntry<bool> ShowWeightText { get; private set; }

		public ConfigEntry<bool> ScaleWeightColor { get; private set; }

		public ConfigEntry<bool> AutoPromoteMainSeat { get; private set; }

		public ConfigEntry<bool> UncapBagScale { get; private set; }

		public ConfigEntry<bool> EnableCarouselHUD { get; private set; }

		public static bool IsBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return Instance._blacklistCacheWithClones.Value.Contains(name);
		}

		public static bool IsRecoveryBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return Instance._recoveryBlacklistCacheWithClones.Value.Contains(name);
		}

		public static bool IsKeywordBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			foreach (string item in Instance._grabbableKeywordBlacklistCache.Value)
			{
				if (name.Contains(item, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsGrabbable(GameObject? obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			if (IsKeywordBlacklisted(((Object)obj).name))
			{
				return false;
			}
			if (IsBlacklisted(((Object)obj).name))
			{
				return false;
			}
			bool flag = false;
			foreach (string item in Instance._grabbableComponentTypesCache.Value)
			{
				Component component = obj.GetComponent(item);
				if ((Object)(object)component != (Object)null)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			foreach (IGrabbingStrategy grabbingStrategy in Instance._grabbingStrategies)
			{
				if (grabbingStrategy.CanGrab(obj))
				{
					return true;
				}
			}
			return false;
		}

		public static void Init(ConfigFile cfg)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			Instance.SearchRangeMultiplier = cfg.Bind<float>("Skill", "SearchRangeMultiplier", 1f, "Multiplier for Drifter's repossess search range");
			Instance.ForwardVelocityMultiplier = cfg.Bind<float>("Skill", "ForwardVelocityMultiplier", 1f, "Multiplier for Drifter's repossess forward velocity");
			Instance.UpwardVelocityMultiplier = cfg.Bind<float>("Skill", "UpwardVelocityMultiplier", 1f, "Multiplier for Drifter's repossess upward velocity");
			Instance.BreakoutTimeMultiplier = cfg.Bind<float>("Skill", "BreakoutTimeMultiplier", 1f, "Multiplier for how long bagged enemies take to break out");
			Instance.MaxSmacks = cfg.Bind<int>("Skill", "MaxSmacks", 3, new ConfigDescription("Maximum number of hits before bagged enemies break out", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			Instance.MassMultiplier = cfg.Bind<string>("Skill", "MassMultiplier", "1", "Multiplier for the mass of bagged objects");
			Instance.EnableBossGrabbing = cfg.Bind<bool>("General", "EnableBossGrabbing", true, "Enable grabbing of boss enemies");
			Instance.EnableNPCGrabbing = cfg.Bind<bool>("General", "EnableNPCGrabbing", false, "Enable grabbing of NPCs with ungrabbable flag");
			Instance.EnableEnvironmentGrabbing = cfg.Bind<bool>("General", "EnableEnvironmentGrabbing", false, "Enable grabbing of environment objects like teleporters, chests, shrines");
			Instance.EnableLockedObjectGrabbing = cfg.Bind<bool>("General", "EnableLockedObjectGrabbing", false, "Enable grabbing of locked objects");
			Instance.ProjectileGrabbingMode = cfg.Bind<ProjectileGrabbingMode>("General", "ProjectileGrabbingMode", DrifterBossGrabMod.ProjectileGrabbingMode.None, "Mode for projectile grabbing: None, Survivor Only, or All Projectiles");
			Instance.EnableDebugLogs = cfg.Bind<bool>("General", "EnableDebugLogs", false, "Enable debug logging");
			Instance.BodyBlacklist = cfg.Bind<string>("General", "Blacklist", "HeaterPodBodyNoRespawn,ThrownObjectProjectile,GenericPickup,MultiShopTerminal,MultiShopLargeTerminal,MultiShopEquipmentTerminal,RailgunnerPistolProjectile,FMJRamping,SyringeProjectile,EngiGrenadeProjectile,CrocoSpit,CaptainTazer,LunarSpike,LunarNeedleProjectile,StickyBomb,RocketProjectile,StunAndPierceBoomerang", "Comma-separated list of body and projectile names to never grab.\nExample: SolusWingBody,Teleporter1,ShrineHalcyonite,PortalShop,RailgunnerPistolProjectile,SyringeProjectile\nAutomatically handles (Clone) - just enter the base name.\nUse debug logs to see body/projectile names, case-insensitive matching");
			Instance.RecoveryObjectBlacklist = cfg.Bind<string>("General", "RecoveryObjectBlacklist", "", "Comma-separated list of object names to never recover from the abyss\nExample: Teleporter1,Chest1,ShrineChance\nAutomatically handles (Clone) - just enter the base name.\nUse debug logs to see object names, case-insensitive matching");
			Instance.GrabbableComponentTypes = cfg.Bind<string>("General", "GrabbableComponentTypes", "PurchaseInteraction,TeleporterInteraction,GenericInteraction,ProxyInteraction,DummyPingableInteraction", "Comma-separated list of component type names that make objects grabbable.\nExample: SurfaceDefProvider,EntityStateMachine,JumpVolume\nObjects must have at least one of these components to be grabbable.\nUse exact component type names (case-sensitive).");
			Instance.GrabbableKeywordBlacklist = cfg.Bind<string>("General", "GrabbableKeywordBlacklist", "Master,Controller", "Comma-separated list of keywords that make objects NOT grabbable if found in their name.\nExample: Master\nObjects with these keywords in their name will be excluded from grabbing.\nCase-insensitive matching, partial matches allowed.\nCase-insensitive matching, partial matches allowed.\n'Master' prevents grabbing enemy masters");
			Instance.EnableConfigSync = cfg.Bind<bool>("General", "EnableConfigSync", true, "Enable synchronization of configuration settings (like environment grabbing) from host to new clients.");
			Instance.EnableComponentAnalysisLogs = cfg.Bind<bool>("General", "EnableComponentAnalysisLogs", false, "Enable scanning of all objects in the current scene to log component types.\nThis can be performance-intensive and should only be enabled for debugging.\nShows all unique component types found in the scene for potential grabbable objects.");
			Instance.EnableObjectPersistence = cfg.Bind<bool>("Persistence", "EnableObjectPersistence", false, "Enable persistence of grabbed objects across stage transitions");
			Instance.EnableAutoGrab = cfg.Bind<bool>("Persistence", "EnableAutoGrab", false, "Automatically re-grab persisted objects on Drifter respawn");
			Instance.PersistBaggedBosses = cfg.Bind<bool>("Persistence", "PersistBaggedBosses", true, "Allow persistence of bagged boss enemies");
			Instance.PersistBaggedNPCs = cfg.Bind<bool>("Persistence", "PersistBaggedNPCs", true, "Allow persistence of bagged NPCs");
			Instance.PersistBaggedEnvironmentObjects = cfg.Bind<bool>("Persistence", "PersistBaggedEnvironmentObjects", true, "Allow persistence of bagged environment objects");
			Instance.PersistenceBlacklist = cfg.Bind<string>("Persistence", "PersistenceBlacklist", "", "Comma-separated list of object names to never persist.\nExample: Teleporter1,Chest1,ShrineChance\nAutomatically handles (Clone) - just enter the base name.\nUse debug logs to see object names, case-insensitive matching");
			Instance.AutoGrabDelay = cfg.Bind<float>("Persistence", "AutoGrabDelay", 1f, "Delay before auto-grabbing persisted objects on stage start (seconds)");
			Instance.BottomlessBagEnabled = cfg.Bind<bool>("Bottomless Bag", "EnableBottomlessBag", false, "Allows the scroll wheel to cycle through stored passengers. Bag capacity scales with the number of repossesses.");
			Instance.BottomlessBagBaseCapacity = cfg.Bind<int>("Bottomless Bag", "BaseCapacity", 0, "Base capacity for bottomless bag, added to utility max stocks");
			Instance.EnableStockRefreshClamping = cfg.Bind<bool>("Bottomless Bag", "EnableStockRefreshClamping", false, "When enabled, Repossess stock refresh is clamped to max stocks minus number of bagged items");
			Instance.CycleCooldown = cfg.Bind<float>("Bottomless Bag", "CycleCooldown", 0.2f, "Cooldown between passenger cycles (seconds)");
			Instance.EnableMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "EnableMouseWheelScrolling", true, "Enable mouse wheel scrolling for cycling passengers");
			Instance.InverseMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "InverseMouseWheelScrolling", false, "Invert the mouse wheel scrolling direction");
			Instance.ScrollUpKeybind = cfg.Bind<KeyboardShortcut>("Bottomless Bag", "ScrollUpKeybind", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Keybind to scroll up through passengers");
			Instance.ScrollDownKeybind = cfg.Bind<KeyboardShortcut>("Bottomless Bag", "ScrollDownKeybind", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Keybind to scroll down through passengers");
			Instance.EnableCarouselHUD = cfg.Bind<bool>("Hud", "EnableCarouselHUD", false, "Enable the custom Carousel HUD for the Drifter's bag. If disabled, reverts to the vanilla UI behavior.");
			Instance.CarouselSpacing = cfg.Bind<float>("Hud", "CarouselSpacing", 45f, "Vertical spacing for carousel items");
			Instance.CarouselCenterOffsetX = cfg.Bind<float>("Hud", "CarouselCenterOffsetX", 25f, "Horizontal offset for the center carousel item");
			Instance.CarouselCenterOffsetY = cfg.Bind<float>("Hud", "CarouselCenterOffsetY", 40f, "Vertical offset for the center carousel item");
			Instance.CarouselSideOffsetX = cfg.Bind<float>("Hud", "CarouselSideOffsetX", 20f, "Horizontal offset for the side carousel items");
			Instance.CarouselSideOffsetY = cfg.Bind<float>("Hud", "CarouselSideOffsetY", 5f, "Vertical offset for the side carousel items");
			Instance.CarouselSideScale = cfg.Bind<float>("Hud", "CarouselSideScale", 0.8f, "Scale for side carousel items");
			Instance.CarouselSideOpacity = cfg.Bind<float>("Hud", "CarouselSideOpacity", 0.3f, "Opacity for side carousel items");
			Instance.CarouselAnimationDuration = cfg.Bind<float>("Hud", "CarouselAnimationDuration", 0.4f, "Duration of carousel animation in seconds");
			Instance.BagUIShowIcon = cfg.Bind<bool>("Hud", "BagUIShowIcon", true, "Show icon in additional Bag UI elements");
			Instance.BagUIShowWeight = cfg.Bind<bool>("Hud", "BagUIShowWeight", true, "Show weight indicator in additional Bag UI elements");
			Instance.BagUIShowName = cfg.Bind<bool>("Hud", "BagUIShowName", true, "Show name in additional Bag UI elements");
			Instance.BagUIShowHealthBar = cfg.Bind<bool>("Hud", "BagUIShowHealthBar", true, "Show health bar in additional Bag UI elements");
			Instance.UseNewWeightIcon = cfg.Bind<bool>("Hud", "UseNewWeightIcon", false, "Use the new custom weight icon instead of the original");
			Instance.ShowWeightText = cfg.Bind<bool>("Hud", "ShowWeightText", false, "Show weight multiplier text on the weight icon");
			Instance.ScaleWeightColor = cfg.Bind<bool>("Hud", "ScaleWeightColor", true, "Scale the weight icon color based on mass");
			Instance.AutoPromoteMainSeat = cfg.Bind<bool>("Bottomless Bag", "AutoPromoteMainSeat", true, "Automatically promote the next object in the bag to the main seat when the current main object is removed.");
			Instance.UncapBagScale = cfg.Bind<bool>("Balance", "UncapBagScale", false, "When enabled, the bag size will not be capped and will continue to grow based on the mass of the stored object(s).");
			Instance.EnableCarouselHUD.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.BagUIShowIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.BagUIShowWeight.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.BagUIShowName.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.BagUIShowHealthBar.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.UseNewWeightIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.ShowWeightText.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.ScaleWeightColor.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance._blacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.BodyBlacklist.Value)) ? (from s in Instance.BodyBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._blacklistCacheWithClones = new LazyCachedValue<HashSet<string>>(delegate
			{
				HashSet<string> value2 = Instance._blacklistCache.Value;
				HashSet<string> hashSet2 = new HashSet<string>(value2, StringComparer.OrdinalIgnoreCase);
				foreach (string item in value2)
				{
					hashSet2.Add(item + "(Clone)");
				}
				return hashSet2;
			});
			Instance._recoveryBlacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.RecoveryObjectBlacklist.Value)) ? (from s in Instance.RecoveryObjectBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._recoveryBlacklistCacheWithClones = new LazyCachedValue<HashSet<string>>(delegate
			{
				HashSet<string> value = Instance._recoveryBlacklistCache.Value;
				HashSet<string> hashSet = new HashSet<string>(value, StringComparer.OrdinalIgnoreCase);
				foreach (string item2 in value)
				{
					hashSet.Add(item2 + "(Clone)");
				}
				return hashSet;
			});
			Instance._grabbableComponentTypesCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.GrabbableComponentTypes.Value)) ? (from s in Instance.GrabbableComponentTypes.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.Ordinal) : new HashSet<string>());
			Instance._grabbableKeywordBlacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.GrabbableKeywordBlacklist.Value)) ? (from s in Instance.GrabbableKeywordBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance.BodyBlacklist.SettingChanged += delegate
			{
				Instance._blacklistCache.Invalidate();
				Instance._blacklistCacheWithClones.Invalidate();
			};
			Instance.RecoveryObjectBlacklist.SettingChanged += delegate
			{
				Instance._recoveryBlacklistCache.Invalidate();
				Instance._recoveryBlacklistCacheWithClones.Invalidate();
			};
			Instance.GrabbableComponentTypes.SettingChanged += delegate
			{
				Instance._grabbableComponentTypesCache.Invalidate();
			};
			Instance.GrabbableKeywordBlacklist.SettingChanged += delegate
			{
				Instance._grabbableKeywordBlacklistCache.Invalidate();
			};
		}

		public static void RemoveEventHandlers(EventHandler debugLogsHandler, EventHandler blacklistHandler, EventHandler forwardVelHandler, EventHandler upwardVelHandler, EventHandler recoveryBlacklistHandler, EventHandler grabbableComponentTypesHandler, EventHandler grabbableKeywordBlacklistHandler, EventHandler bossGrabbingHandler, EventHandler npcGrabbingHandler, EventHandler environmentGrabbingHandler, EventHandler lockedObjectGrabbingHandler, EventHandler projectileGrabbingModeHandler)
		{
			Instance.EnableDebugLogs.SettingChanged -= debugLogsHandler;
			Instance.BodyBlacklist.SettingChanged -= blacklistHandler;
			Instance.ForwardVelocityMultiplier.SettingChanged -= forwardVelHandler;
			Instance.UpwardVelocityMultiplier.SettingChanged -= upwardVelHandler;
			Instance.RecoveryObjectBlacklist.SettingChanged -= recoveryBlacklistHandler;
			Instance.GrabbableComponentTypes.SettingChanged -= grabbableComponentTypesHandler;
			Instance.GrabbableKeywordBlacklist.SettingChanged -= grabbableKeywordBlacklistHandler;
			Instance.EnableBossGrabbing.SettingChanged -= bossGrabbingHandler;
			Instance.EnableNPCGrabbing.SettingChanged -= npcGrabbingHandler;
			Instance.EnableEnvironmentGrabbing.SettingChanged -= environmentGrabbingHandler;
			Instance.EnableLockedObjectGrabbing.SettingChanged -= lockedObjectGrabbingHandler;
			Instance.ProjectileGrabbingMode.SettingChanged -= projectileGrabbingModeHandler;
		}

		public static void ClearBlacklistCache()
		{
			Instance._blacklistCache.Invalidate();
			Instance._blacklistCacheWithClones.Invalidate();
		}

		public static void ClearRecoveryBlacklistCache()
		{
			Instance._recoveryBlacklistCache.Invalidate();
			Instance._recoveryBlacklistCacheWithClones.Invalidate();
		}

		public static void ClearGrabbableComponentTypesCache()
		{
			Instance._grabbableComponentTypesCache.Invalidate();
		}

		public static void ClearGrabbableKeywordBlacklistCache()
		{
			Instance._grabbableKeywordBlacklistCache.Invalidate();
		}

		private static void UpdateBagUIToggles()
		{
			BaggedObjectCarousel[] array = Object.FindObjectsByType<BaggedObjectCarousel>((FindObjectsSortMode)0);
			BaggedObjectCarousel[] array2 = array;
			foreach (BaggedObjectCarousel baggedObjectCarousel in array2)
			{
				baggedObjectCarousel.UpdateToggles();
			}
		}

		private static Transform? FindDeepChild(Transform parent, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name == name)
				{
					return val;
				}
				Transform val2 = FindDeepChild(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}
	}
	internal static class Constants
	{
		public const string CloneSuffix = "(Clone)";

		public const string PluginGuid = "pwdcat.DrifterBossGrab";

		public const string PluginName = "DrifterBossGrab";

		public const string PluginVersion = "1.6.10";
	}
	public static class FeatureState
	{
		public static bool IsCyclingEnabled => PluginConfig.Instance.BottomlessBagEnabled.Value;
	}
	public abstract class FeatureToggleBase : IFeatureToggle
	{
		public abstract string FeatureName { get; }

		public abstract bool IsEnabled { get; }

		protected abstract void ApplyPatches(Harmony harmony);

		public void Initialize(Harmony harmony)
		{
			if (IsEnabled)
			{
				ApplyPatches(harmony);
			}
		}

		public virtual void Cleanup(Harmony harmony)
		{
			Log.Info("[" + FeatureName + "] Cleaning up patches...");
			harmony.UnpatchSelf();
		}

		public void Enable(Harmony harmony)
		{
			if (!IsEnabled)
			{
				Log.Info("[" + FeatureName + "] Enable called but IsEnabled is false. Aborting.");
				return;
			}
			Log.Info("[" + FeatureName + "] Enabling feature and applying patches...");
			ApplyPatches(harmony);
		}

		public void Disable(Harmony harmony)
		{
			Log.Info("[" + FeatureName + "] Disabling feature...");
			Cleanup(harmony);
		}

		public void Toggle(Harmony harmony, bool enable)
		{
			Log.Info($"[{FeatureName}] Toggle called with enable={enable}");
			if (enable)
			{
				Enable(harmony);
			}
			else
			{
				Disable(harmony);
			}
		}
	}
	public class PatchFactory : IPatchFactory, IConfigurable
	{
		private readonly List<Type> registeredPatchTypes = new List<Type>();

		private Harmony? harmonyInstance;

		public static IPatchFactory Instance { get; } = new PatchFactory();


		public void RegisterPatch(Type patchType)
		{
			if (patchType == null)
			{
				throw new ArgumentNullException("patchType");
			}
			registeredPatchTypes.Add(patchType);
		}

		public void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			harmonyInstance = new Harmony("pwdcat.DrifterBossGrab");
			foreach (Type registeredPatchType in registeredPatchTypes)
			{
				try
				{
					MethodInfo method = registeredPatchType.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public);
					if (method != null)
					{
						method.Invoke(null, null);
					}
				}
				catch (Exception ex)
				{
					Log.Error("Failed to initialize patch " + registeredPatchType.Name + ": " + ex.Message);
				}
			}
		}

		public void CleanupPatches()
		{
			foreach (Type registeredPatchType in registeredPatchTypes)
			{
				try
				{
					MethodInfo method = registeredPatchType.GetMethod("Cleanup", BindingFlags.Static | BindingFlags.Public);
					if (method != null)
					{
						method.Invoke(null, null);
					}
				}
				catch (Exception ex)
				{
					Log.Error("Failed to cleanup patch " + registeredPatchType.Name + ": " + ex.Message);
				}
			}
			registeredPatchTypes.Clear();
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
				harmonyInstance = null;
			}
		}

		public IEnumerable<Type> GetRegisteredPatchTypes()
		{
			return registeredPatchTypes.AsReadOnly();
		}

		void IConfigurable.Initialize()
		{
			ApplyPatches();
		}

		void IConfigurable.Cleanup()
		{
			CleanupPatches();
		}
	}
	[BepInPlugin("pwdcat.DrifterBossGrab", "DrifterBossGrab", "1.6.10")]
	public class DrifterBossGrabPlugin : BaseUnityPlugin, IConfigObserver
	{
		[CompilerGenerated]
		private sealed class <DelayedBatchSpecialObjectAttributesInitialization>d__68 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private GameObject[] <allObjects>5__2;

			private int <i>5__3;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedBatchSpecialObjectAttributesInitialization>d__68(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<allObjects>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (PluginConfig.Instance.EnableDebugLogs.Value)
					{
						Log.Info($"[DelayedBatchSpecialObjectAttributesInitialization] IsDrifterPresent: {IsDrifterPresent}");
					}
					if (!IsDrifterPresent)
					{
						return false;
					}
					<allObjects>5__2 = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0);
					<i>5__3 = 0;
					goto IL_0103;
				case 2:
					{
						<>1__state = -1;
						goto IL_00f4;
					}
					IL_00f4:
					<i>5__3 += 50;
					goto IL_0103;
					IL_0103:
					if (<i>5__3 < <allObjects>5__2.Length)
					{
						int num = Mathf.Min(<i>5__3 + 50, <allObjects>5__2.Length);
						for (int i = <i>5__3; i < num; i++)
						{
							GameObject val = <allObjects>5__2[i];
							if ((Object)(object)val != (Object)null && PluginConfig.IsGrabbable(val))
							{
								GrabbableObjectPatches.AddSpecialObjectAttributesToGrabbableObject(val);
							}
						}
						if (num < <allObjects>5__2.Length)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						goto IL_00f4;
					}
					if (PluginConfig.Instance.EnableDebugLogs.Value)
					{
						Log.Info($"[DelayedBatchSpecialObjectAttributesInitialization] Completed batched SpecialObjectAttributes initialization for {<allObjects>5__2.Length} objects");
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedEnsureSpecialObjectAttributes>d__67 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedEnsureSpecialObjectAttributes>d__67(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (IsDrifterPresent)
					{
						GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedGrabbableComponentTypesUpdate>d__70 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedGrabbableComponentTypesUpdate>d__70(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					PluginConfig.ClearGrabbableComponentTypesCache();
					if (IsDrifterPresent)
					{
						GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
					}
					_grabbableComponentTypesUpdateCoroutine = null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateDrifterPresence>d__69 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateDrifterPresence>d__69(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					IsDrifterPresent = (Object)(object)Object.FindAnyObjectByType<DrifterBagController>() != (Object)null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const short BAGGED_OBJECTS_PERSISTENCE_MSG_TYPE = 85;

		private static Coroutine? _grabbableComponentTypesUpdateCoroutine;

		public static bool _isSwappingPassengers;

		private DrifterGrabFeature? _drifterGrabFeature;

		private BottomlessBagFeature? _bottomlessBagFeature;

		private PersistenceFeature? _persistenceFeature;

		private Harmony? _drifterGrabHarmony;

		private Harmony? _bottomlessBagHarmony;

		private Harmony? _persistenceHarmony;

		private bool _wasBottomlessBagEnabled;

		private bool _wasPersistenceEnabled;

		private ConfigurationComposite? _configurationComposite;

		private EventHandler? debugLogsHandler;

		private EventHandler? blacklistHandler;

		private EventHandler? forwardVelHandler;

		private EventHandler? upwardVelHandler;

		private EventHandler? recoveryBlacklistHandler;

		private EventHandler? grabbableComponentTypesHandler;

		private EventHandler? grabbableKeywordBlacklistHandler;

		private EventHandler? bossGrabbingHandler;

		private EventHandler? npcGrabbingHandler;

		private EventHandler? environmentGrabbingHandler;

		private EventHandler? lockedObjectGrabbingHandler;

		private EventHandler? projectileGrabbingModeHandler;

		private EventHandler? persistenceHandler;

		private EventHandler? autoGrabHandler;

		private EventHandler? bottomlessBagToggleHandler;

		private EventHandler? persistenceToggleHandler;

		public static DrifterBossGrabPlugin? Instance { get; private set; }

		public static bool RooInstalled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		public string DirectoryName => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);

		public static bool IsSwappingPassengers => _isSwappingPassengers;

		public static bool IsDrifterPresent { get; set; }

		private void InitializeInstance()
		{
			Instance = this;
		}

		private void InitializeCoreSystems()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			PluginConfig.Init(((BaseUnityPlugin)this).Config);
			StateManagement.Initialize(PluginConfig.Instance.EnableDebugLogs.Value);
			Log.EnableDebugLogs = PluginConfig.Instance.EnableDebugLogs.Value;
		}

		private void InitializeConfigurationComposite()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			_configurationComposite = new ConfigurationComposite();
			_drifterGrabHarmony = new Harmony("pwdcat.DrifterBossGrab.driftergrab");
			_bottomlessBagHarmony = new Harmony("pwdcat.DrifterBossGrab.bottomlessbag");
			_persistenceHarmony = new Harmony("pwdcat.DrifterBossGrab.persistence");
			_drifterGrabFeature = new DrifterGrabFeature();
			_drifterGrabFeature.Initialize(_drifterGrabHarmony);
			_bottomlessBagFeature = new BottomlessBagFeature();
			_bottomlessBagFeature.Initialize(_bottomlessBagHarmony);
			_wasBottomlessBagEnabled = PluginConfig.Instance.BottomlessBagEnabled.Value;
			_persistenceFeature = new PersistenceFeature();
			_persistenceFeature.Initialize(_persistenceHarmony);
			_wasPersistenceEnabled = PluginConfig.Instance.EnableObjectPersistence.Value;
			_configurationComposite.AddComponent((IConfigurable)PatchFactory.Instance);
			_configurationComposite.AddComponent(new PersistenceManagerWrapper());
			_configurationComposite.Initialize();
		}

		public void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			InitializeInstance();
			InitializeCoreSystems();
			InitializeConfigurationComposite();
			ConfigChangeNotifier.Init();
			ConfigChangeNotifier.AddObserver(this);
			SetupConfigurationEventHandlers();
			SetupFeatureToggleHandlers();
			RegisterGameEvents();
			BagStateSync.Init(new Harmony("pwdcat.DrifterBossGrab.networking"));
			ConfigSyncHandler.Init();
		}

		private void RemoveConfigurationEventHandlers()
		{
			PluginConfig.RemoveEventHandlers(debugLogsHandler ?? ((EventHandler)delegate
			{
			}), blacklistHandler ?? ((EventHandler)delegate
			{
			}), forwardVelHandler ?? ((EventHandler)delegate
			{
			}), upwardVelHandler ?? ((EventHandler)delegate
			{
			}), recoveryBlacklistHandler ?? ((EventHandler)delegate
			{
			}), grabbableComponentTypesHandler ?? ((EventHandler)delegate
			{
			}), grabbableKeywordBlacklistHandler ?? ((EventHandler)delegate
			{
			}), bossGrabbingHandler ?? ((EventHandler)delegate
			{
			}), npcGrabbingHandler ?? ((EventHandler)delegate
			{
			}), environmentGrabbingHandler ?? ((EventHandler)delegate
			{
			}), lockedObjectGrabbingHandler ?? ((EventHandler)delegate
			{
			}), projectileGrabbingModeHandler ?? ((EventHandler)delegate
			{
			}));
		}

		private void RemovePersistenceEventHandlers()
		{
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged -= persistenceHandler;
			PluginConfig.Instance.EnableAutoGrab.SettingChanged -= autoGrabHandler;
		}

		private void RemoveFeatureToggleHandlers()
		{
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged -= bottomlessBagToggleHandler;
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged -= persistenceToggleHandler;
		}

		private void CleanupConfigurationComposite()
		{
			_configurationComposite?.Cleanup();
			_drifterGrabFeature?.Cleanup(_drifterGrabHarmony);
			_bottomlessBagFeature?.Cleanup(_bottomlessBagHarmony);
			_persistenceFeature?.Cleanup(_persistenceHarmony);
		}

		private void StopCoroutines()
		{
			if (_grabbableComponentTypesUpdateCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_grabbableComponentTypesUpdateCoroutine);
				_grabbableComponentTypesUpdateCoroutine = null;
			}
		}

		private void SetupFeatureToggleHandlers()
		{
			bottomlessBagToggleHandler = delegate
			{
				bool value2 = PluginConfig.Instance.BottomlessBagEnabled.Value;
				if (value2 != _wasBottomlessBagEnabled)
				{
					_bottomlessBagFeature?.Toggle(_bottomlessBagHarmony, value2);
					_wasBottomlessBagEnabled = value2;
					if (PluginConfig.Instance.EnableDebugLogs.Value)
					{
						Log.Info("[FeatureToggle] BottomlessBag feature " + (value2 ? "enabled" : "disabled") + " at runtime");
					}
				}
			};
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged += bottomlessBagToggleHandler;
			persistenceToggleHandler = delegate
			{
				bool value = PluginConfig.Instance.EnableObjectPersistence.Value;
				if (value != _wasPersistenceEnabled)
				{
					_persistenceFeature?.Toggle(_persistenceHarmony, value);
					_wasPersistenceEnabled = value;
					if (PluginConfig.Instance.EnableDebugLogs.Value)
					{
						Log.Info("[FeatureToggle] Persistence feature " + (value ? "enabled" : "disabled") + " at runtime");
					}
				}
			};
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged += persistenceToggleHandler;
		}

		public void OnDestroy()
		{
			RemoveConfigurationEventHandlers();
			RemovePersistenceEventHandlers();
			RemoveFeatureToggleHandlers();
			CleanupConfigurationComposite();
			StopCoroutines();
		}

		public void OnConfigChanged(string key, object value)
		{
			if (PluginConfig.Instance.EnableDebugLogs.Value)
			{
				Log.Info($"[OnConfigChanged] Config changed: {key} = {value}");
			}
		}

		public void Start()
		{
			SetupRiskOfOptions();
		}

		public void Update()
		{
			if (FeatureState.IsCyclingEnabled)
			{
				BottomlessBagPatches.HandleInput();
			}
		}

		private void SetupConfigurationEventHandlers()
		{
			SetupDebugLogsHandler();
			SetupBlacklistHandlers();
			SetupVelocityHandlers();
			SetupGrabbableHandlers();
			SetupGrabbingHandlers();
			SetupPersistenceHandlers();
			PersistenceManager.UpdateCachedConfig();
		}

		private void SetupDebugLogsHandler()
		{
			debugLogsHandler = delegate
			{
				Log.EnableDebugLogs = PluginConfig.Instance.EnableDebugLogs.Value;
				StateManagement.UpdateDebugLogging(PluginConfig.Instance.EnableDebugLogs.Value);
			};
			PluginConfig.Instance.EnableDebugLogs.SettingChanged += debugLogsHandler;
		}

		private void SetupBlacklistHandlers()
		{
			blacklistHandler = delegate
			{
				PluginConfig.ClearBlacklistCache();
			};
			PluginConfig.Instance.BodyBlacklist.SettingChanged += blacklistHandler;
			recoveryBlacklistHandler = delegate
			{
				PluginConfig.ClearRecoveryBlacklistCache();
			};
			PluginConfig.Instance.RecoveryObjectBlacklist.SettingChanged += recoveryBlacklistHandler;
		}

		private void SetupVelocityHandlers()
		{
			forwardVelHandler = RepossessPatches.OnForwardVelocityChanged;
			PluginConfig.Instance.ForwardVelocityMultiplier.SettingChanged += forwardVelHandler;
			upwardVelHandler = RepossessPatches.OnUpwardVelocityChanged;
			PluginConfig.Instance.UpwardVelocityMultiplier.SettingChanged += upwardVelHandler;
		}

		private void SetupGrabbableHandlers()
		{
			grabbableComponentTypesHandler = delegate
			{
				if (_grabbableComponentTypesUpdateCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_grabbableComponentTypesUpdateCoroutine);
				}
				_grabbableComponentTypesUpdateCoroutine = ((MonoBehaviour)this).StartCoroutine(DelayedGrabbableComponentTypesUpdate());
			};
			PluginConfig.Instance.GrabbableComponentTypes.SettingChanged += grabbableComponentTypesHandler;
			grabbableKeywordBlacklistHandler = delegate
			{
				PluginConfig.ClearGrabbableKeywordBlacklistCache();
			};
			PluginConfig.Instance.GrabbableKeywordBlacklist.SettingChanged += grabbableKeywordBlacklistHandler;
		}

		private void SetupGrabbingHandlers()
		{
			bossGrabbingHandler = delegate
			{
				if (IsDrifterPresent)
				{
					GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
				}
			};
			PluginConfig.Instance.EnableBossGrabbing.SettingChanged += bossGrabbingHandler;
			npcGrabbingHandler = delegate
			{
				if (IsDrifterPresent)
				{
					GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
				}
			};
			PluginConfig.Instance.EnableNPCGrabbing.SettingChanged += npcGrabbingHandler;
			environmentGrabbingHandler = delegate
			{
				if (IsDrifterPresent)
				{
					GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
				}
			};
			PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged += environmentGrabbingHandler;
			lockedObjectGrabbingHandler = delegate
			{
			};
			PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged += lockedObjectGrabbingHandler;
			projectileGrabbingModeHandler = delegate
			{
				if (IsDrifterPresent)
				{
					GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
				}
			};
			PluginConfig.Instance.ProjectileGrabbingMode.SettingChanged += projectileGrabbingModeHandler;
		}

		private void SetupPersistenceHandlers()
		{
			persistenceHandler = delegate
			{
				PersistenceManager.UpdateCachedConfig();
			};
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged += persistenceHandler;
			autoGrabHandler = delegate
			{
				PersistenceManager.UpdateCachedConfig();
			};
			PluginConfig.Instance.EnableAutoGrab.SettingChanged += autoGrabHandler;
		}

		private void RegisterGameEvents()
		{
			Run.onPlayerFirstCreatedServer += OnPlayerFirstCreated;
			SceneManager.activeSceneChanged += OnSceneChanged;
			CharacterBody.onBodyStartGlobal += OnBodyStart;
		}

		private void OnBodyStart(CharacterBody body)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)body) && body.bodyIndex == BodyCatalog.FindBodyIndex("DrifterBody"))
			{
				if (PluginConfig.Instance.EnableDebugLogs.Value)
				{
					Log.Info("[Plugin] Drifter body spawned: " + ((Object)body).name + ". Triggering object scan.");
				}
				IsDrifterPresent = true;
				GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
			}
		}

		private static void OnPlayerFirstCreated(Run run, PlayerCharacterMasterController pcm)
		{
			if ((Object)(object)pcm != (Object)null && (Object)(object)pcm.networkUser != (Object)null && ((NetworkBehaviour)pcm.networkUser).connectionToClient != null)
			{
				ConfigSyncHandler.SendConfigToClient(((NetworkBehaviour)pcm.networkUser).connectionToClient);
			}
		}

		private static void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			IsDrifterPresent = false;
			OtherPatches.ResetZoneInversionDetection();
			PersistenceSceneHandler.Instance.OnSceneChanged(oldScene, newScene);
			if ((Object)(object)Instance != (Object)null)
			{
				((MonoBehaviour)Instance).StartCoroutine(DelayedUpdateDrifterPresence());
				((MonoBehaviour)Instance).StartCoroutine(DelayedEnsureSpecialObjectAttributes());
				((MonoBehaviour)Instance).StartCoroutine(DelayedBatchSpecialObjectAttributesInitialization());
			}
			BagPatches.ScanAllSceneComponents();
		}

		[IteratorStateMachine(typeof(<DelayedEnsureSpecialObjectAttributes>d__67))]
		private static IEnumerator DelayedEnsureSpecialObjectAttributes()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedEnsureSpecialObjectAttributes>d__67(0);
		}

		[IteratorStateMachine(typeof(<DelayedBatchSpecialObjectAttributesInitialization>d__68))]
		private static IEnumerator DelayedBatchSpecialObjectAttributesInitialization()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedBatchSpecialObjectAttributesInitialization>d__68(0);
		}

		[IteratorStateMachine(typeof(<DelayedUpdateDrifterPresence>d__69))]
		private static IEnumerator DelayedUpdateDrifterPresence()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedUpdateDrifterPresence>d__69(0);
		}

		[IteratorStateMachine(typeof(<DelayedGrabbableComponentTypesUpdate>d__70))]
		private static IEnumerator DelayedGrabbableComponentTypesUpdate()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedGrabbableComponentTypesUpdate>d__70(0);
		}

		private void SetupRiskOfOptions()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (RooInstalled)
			{
				ModSettingsManager.SetModDescription("Allows Drifter to grab bosses, NPCs, and environment objects.", "pwdcat.DrifterBossGrab", "DrifterBossGrab");
				try
				{
					byte[] array = File.ReadAllBytes(Path.Combine(DirectoryName, "icon.png"));
					Texture2D val = new Texture2D(256, 256);
					ImageConversion.LoadImage(val, array);
					ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f)));
				}
				catch (Exception)
				{
				}
				AddConfigurationOptions();
			}
		}

		private void AddConfigurationOptions()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Expected O, but got Unknown
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Expected O, but got Unknown
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Expected O, but got Unknown
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Expected O, but got Unknown
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Expected O, but got Unknown
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Expected O, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Expected O, but got Unknown
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Expected O, but got Unknown
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Expected O, but got Unknown
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Expected O, but got Unknown
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Expected O, but got Unknown
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Expected O, but got Unknown
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Expected O, but got Unknown
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Expected O, but got Unknown
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Expected O, but got Unknown
			if (RooInstalled)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableBossGrabbing));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableNPCGrabbing));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableEnvironmentGrabbing));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableLockedObjectGrabbing));
				ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)PluginConfig.Instance.ProjectileGrabbingMode));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableObjectPersistence));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableAutoGrab));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.PersistBaggedBosses));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.PersistBaggedNPCs));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.PersistBaggedEnvironmentObjects));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.PersistenceBlacklist));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.AutoGrabDelay, new StepSliderConfig
				{
					min = 0f,
					max = 10f,
					increment = 0.1f
				}));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.SearchRangeMultiplier));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.ForwardVelocityMultiplier));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.UpwardVelocityMultiplier));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.BreakoutTimeMultiplier));
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(PluginConfig.Instance.MaxSmacks));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.MassMultiplier));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.BodyBlacklist));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.GrabbableComponentTypes));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.GrabbableKeywordBlacklist));
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PluginConfig.Instance.RecoveryObjectBlacklist));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableDebugLogs));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableComponentAnalysisLogs));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.BottomlessBagEnabled));
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(PluginConfig.Instance.BottomlessBagBaseCapacity));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableStockRefreshClamping));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.Instance.CycleCooldown, new StepSliderConfig
				{
					min = 0f,
					max = 1f,
					increment = 0.01f
				}));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.AutoPromoteMainSeat));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableMouseWheelScrolling));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.InverseMouseWheelScrolling));
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(PluginConfig.Instance.ScrollUpKeybind));
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(PluginConfig.Instance.ScrollDownKeybind));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.EnableCarouselHUD));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselSpacing));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselCenterOffsetX));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselCenterOffsetY));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselSideOffsetX));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselSideOffsetY));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselSideScale));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselSideOpacity));
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(PluginConfig.Instance.CarouselAnimationDuration));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.BagUIShowIcon));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.BagUIShowWeight));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.BagUIShowName));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.BagUIShowHealthBar));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.UseNewWeightIcon));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.ShowWeightText));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.ScaleWeightColor));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.Instance.UncapBagScale));
			}
		}
	}
	public static class StateManagement
	{
		internal static bool cachedDebugLogsEnabled;

		public static void Initialize(bool debugLogsEnabled)
		{
			cachedDebugLogsEnabled = debugLogsEnabled;
		}

		public static void UpdateDebugLogging(bool debugLogsEnabled)
		{
			cachedDebugLogsEnabled = debugLogsEnabled;
		}

		public static void DisableMovementColliders(GameObject obj, Dictionary<GameObject, bool> originalStates)
		{
			ModelLocator component = obj.GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelTransform))
			{
				return;
			}
			Transform[] componentsInChildren = ((Component)component.modelTransform).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				Collider component2 = ((Component)val).GetComponent<Collider>();
				if ((Object)(object)component2 != (Object)null)
				{
					if (!originalStates.ContainsKey(((Component)val).gameObject))
					{
						originalStates[((Component)val).gameObject] = ((Component)val).gameObject.activeSelf;
					}
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		public static void RestoreMovementColliders(Dictionary<GameObject, bool> originalStates)
		{
			foreach (KeyValuePair<GameObject, bool> originalState in originalStates)
			{
				if ((Object)(object)originalState.Key != (Object)null)
				{
					originalState.Key.SetActive(originalState.Value);
				}
			}
			originalStates.Clear();
		}
	}
	public class BottomlessBagFeature : FeatureToggleBase
	{
		public override string FeatureName => "BottomlessBag";

		public override bool IsEnabled => PluginConfig.Instance.BottomlessBagEnabled.Value;

		protected override void ApplyPatches(Harmony harmony)
		{
			Log.Info("[" + FeatureName + "] Applying patches...");
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.BaggedObject_TryOverrideUtility)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.BaggedObject_TryOverridePrimary)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.BaggedObject_OnEnter)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.BaggedObject_OnExit)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.BaggedObject_FixedUpdate)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.VehicleSeat_FixedUpdate)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.VehicleSeat_EjectPassenger)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.EntityStateMachine_SetNextStateToMain)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.EntityState_OnEnter_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(BaggedObjectPatches.GenericSkill_ExecuteIfReady_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(VehicleSeat_AssignPassenger_Postfix)).Patch();
			harmony.CreateClassProcessor(typeof(GlobalEventManager_OnCharacterDeath)).Patch();
			harmony.CreateClassProcessor(typeof(SkillPatches.GenericSkill_RestockSteplike)).Patch();
			harmony.CreateClassProcessor(typeof(SkillPatches.GenericSkill_Reset)).Patch();
			harmony.CreateClassProcessor(typeof(SkillPatches.GenericSkill_RunRecharge)).Patch();
			Log.Info("[" + FeatureName + "] Patches applied successfully.");
		}
	}
	public class DrifterGrabFeature : FeatureToggleBase
	{
		public override string FeatureName => "DrifterGrab";

		public override bool IsEnabled => true;

		protected override void ApplyPatches(Harmony harmony)
		{
			Log.Info("[" + FeatureName + "] Applying patches...");
			harmony.CreateClassProcessor(typeof(BagPatches.Run_Start_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(BagPatches.DrifterBagController_AssignPassenger)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.HackingMainState_FixedUpdate_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.ThrownObjectProjectileController_OnSyncPassenger_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.ThrownObjectProjectileController_CheckForDeadPassenger_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.ThrownObjectProjectileController_ImpactBehavior_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.MapZoneChecker_FixedUpdate_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.ProjectileFuse_FixedUpdate_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.SpecialObjectAttributes_Start_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.BaggedObject_OnEnter_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(OtherPatches.ThrownObjectProjectileController_EjectPassengerToFinalPosition_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessExitPatches.RepossessExit_OnEnter_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessExitPatches.BaggedObject_OnEnter_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessExitPatches.BaggedObject_OnExit_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.Repossess_Constructor_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.DrifterBagController_CalculateBaggedObjectMass_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.DrifterBagController_RecalculateBaggedObjectMass_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.DrifterBagController_OnSyncBaggedObject_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.DrifterBagController_Awake_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.BaggedObject_OnEnter_ExtendBreakoutTime)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.SpecialObjectAttributes_get_isTargetable)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.RepossessBullseyeSearch_HurtBoxPassesRequirements)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.SpecialObjectAttributes_AvoidCapture)).Patch();
			harmony.CreateClassProcessor(typeof(RepossessPatches.Repossess_OnExit_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(CharacterSpawnPatches.CharacterMaster_OnBodyStart)).Patch();
			harmony.CreateClassProcessor(typeof(UIPatches.BaggedObject_OnUIOverlayInstanceAdded)).Patch();
			harmony.CreateClassProcessor(typeof(GrabbableObjectPatches.DirectorCore_TrySpawnObject_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(GrabbableObjectPatches.SpecialObjectAttributes_Start_Patch)).Patch();
			harmony.CreateClassProcessor(typeof(ProjectilePatches.ProjectileController_Start_Patch)).Patch();
			Log.Info("[" + FeatureName + "] Patches applied successfully.");
		}
	}
	public class PersistenceFeature : FeatureToggleBase
	{
		public override string FeatureName => "Persistence";

		public override bool IsEnabled => PluginConfig.Instance.EnableObjectPersistence.Value;

		protected override void ApplyPatches(Harmony harmony)
		{
			Log.Info("[" + FeatureName + "] Applying patches...");
			harmony.CreateClassProcessor(typeof(SceneExitPatches.SceneExitController_OnEnable)).Patch();
			harmony.CreateClassProcessor(typeof(SceneExitPatches.SceneExitController_OnDisable)).Patch();
			harmony.CreateClassProcessor(typeof(TeleporterPatches)).Patch();
			Log.Info("[" + FeatureName + "] Initializing manual patches (RunLifecyclePatches, TeleporterPatches)...");
			RunLifecyclePatches.Initialize();
			TeleporterPatches.Initialize();
			Log.Info("[" + FeatureName + "] Patches applied successfully.");
		}

		public override void Cleanup(Harmony harmony)
		{
			base.Cleanup(harmony);
			Log.Info("[" + FeatureName + "] Cleaning up manual patches...");
			RunLifecyclePatches.Cleanup();
			TeleporterPatches.Cleanup();
			Log.Info("[" + FeatureName + "] Cleanup complete.");
		}
	}
	public interface IConfigObserver
	{
		void OnConfigChanged(string key, object value);
	}
	public interface IConfigurable
	{
		void Initialize();

		void Cleanup();
	}
	public interface IGrabbingStrategy
	{
		bool CanGrab(GameObject obj);
	}
	public enum LogLevel
	{
		Debug,
		Info,
		Warning,
		Error,
		Fatal
	}
	public interface ILogger
	{
		void Log(LogLevel level, string message);
	}
	public interface IPatch
	{
		void Initialize();

		void Cleanup();
	}
	public interface IPatchFactory
	{
		void RegisterPatch(Type patchType);

		void ApplyPatches();

		void CleanupPatches();

		IEnumerable<Type> GetRegisteredPatchTypes();
	}
	public interface IPersistenceManager
	{
		void OnSceneChanged(Scene oldScene, Scene newScene);

		void ScheduleAutoGrab(CharacterMaster master);
	}
	public interface IPluginConfig
	{
		ConfigEntry<float> SearchRangeMultiplier { get; }

		ConfigEntry<float> BreakoutTimeMultiplier { get; }

		ConfigEntry<float> ForwardVelocityMultiplier { get; }

		ConfigEntry<float> UpwardVelocityMultiplier { get; }

		ConfigEntry<bool> EnableBossGrabbing { get; }

		ConfigEntry<bool> EnableNPCGrabbing { get; }

		ConfigEntry<bool> EnableEnvironmentGrabbing { get; }

		ConfigEntry<bool> EnableLockedObjectGrabbing { get; }

		ConfigEntry<ProjectileGrabbingMode> ProjectileGrabbingMode { get; }

		ConfigEntry<int> MaxSmacks { get; }

		ConfigEntry<string> MassMultiplier { get; }

		ConfigEntry<bool> EnableDebugLogs { get; }

		ConfigEntry<string> BodyBlacklist { get; }

		ConfigEntry<string> RecoveryObjectBlacklist { get; }

		ConfigEntry<string> GrabbableComponentTypes { get; }

		ConfigEntry<string> GrabbableKeywordBlacklist { get; }

		ConfigEntry<bool> EnableComponentAnalysisLogs { get; }

		ConfigEntry<bool> EnableObjectPersistence { get; }

		ConfigEntry<bool> EnableAutoGrab { get; }

		ConfigEntry<bool> PersistBaggedBosses { get; }

		ConfigEntry<bool> PersistBaggedNPCs { get; }

		ConfigEntry<bool> PersistBaggedEnvironmentObjects { get; }

		ConfigEntry<string> PersistenceBlacklist { get; }

		ConfigEntry<bool> BottomlessBagEnabled { get; }

		ConfigEntry<int> BottomlessBagBaseCapacity { get; }

		ConfigEntry<bool> EnableMouseWheelScrolling { get; }

		ConfigEntry<KeyboardShortcut> ScrollUpKeybind { get; }

		ConfigEntry<KeyboardShortcut> ScrollDownKeybind { get; }

		bool IsBlacklisted(string? name);

		bool IsRecoveryBlacklisted(string? name);

		bool IsKeywordBlacklisted(string? name);

		bool IsGrabbable(GameObject? obj);

		void Init(ConfigFile cfg);

		void RemoveEventHandlers(EventHandler debugLogsHandler, EventHandler blacklistHandler, EventHandler forwardVelHandler, EventHandler upwardVelHandler, EventHandler recoveryBlacklistHandler, EventHandler grabbableComponentTypesHandler, EventHandler grabbableKeywordBlacklistHandler, EventHandler bossGrabbingHandler, EventHandler npcGrabbingHandler, EventHandler environmentGrabbingHandler, EventHandler lockedObjectGrabbingHandler);

		void ClearBlacklistCache();

		void ClearRecoveryBlacklistCache();

		void ClearGrabbableComponentTypesCache();

		void ClearGrabbableKeywordBlacklistCache();
	}
	public class DebugLogger : ILogger
	{
		public void Log(LogLevel level, string message)
		{
			if (level >= LogLevel.Debug)
			{
				Debug.Log((object)("[DEBUG] " + message));
			}
		}
	}
	public class ErrorLogger : ILogger
	{
		public void Log(LogLevel level, string message)
		{
			if (level >= LogLevel.Error)
			{
				Debug.LogError((object)("[ERROR] " + message));
			}
		}
	}
	public class InfoLogger : ILogger
	{
		public void Log(LogLevel level, string message)
		{
			if (level >= LogLevel.Info)
			{
				Debug.Log((object)("[INFO] " + message));
			}
		}
	}
	internal static class Log
	{
		private static ILogger _logger = new DebugLogger();

		internal static bool EnableDebugLogs
		{
			get
			{
				return _logger is DebugLogger;
			}
			set
			{
				ILogger logger2;
				if (!value)
				{
					ILogger logger = new InfoLogger();
					logger2 = logger;
				}
				else
				{
					ILogger logger = new DebugLogger();
					logger2 = logger;
				}
				_logger = logger2;
			}
		}

		internal static void Init(ManualLogSource logSource)
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error(object data)
		{
			_logger.Log(LogLevel.Error, data.ToString());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal(object data)
		{
			_logger.Log(LogLevel.Fatal, data.ToString());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info(object data)
		{
			_logger.Log(LogLevel.Info, data.ToString());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message(object data)
		{
			_logger.Log(LogLevel.Info, data.ToString());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning(object data)
		{
			_logger.Log(LogLevel.Warning, data.ToString());
		}
	}
	public class ModelStatePreserver : MonoBehaviour
	{
		public bool originalAutoUpdateModelTransform;

		public Vector3 originalInitialPosition;

		public Quaternion originalInitialRotation;

		public Vector3 originalInitialScale;

		public Transform? originalModelParent;

		public Vector3 rootRelativePosition;

		public Quaternion rootRelativeRotation;

		public Vector3 rootRelativeScale;

		private ModelLocator? _modelLocator;

		private readonly Dictionary<Renderer, bool> _rendererStates = new Dictionary<Renderer, bool>();

		private readonly Dictionary<Collider, bool> _colliderStates = new Dictionary<Collider, bool>();

		private void Awake()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: 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_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.Instance.EnableDebugLogs.Value)
			{
				Log.Info("[ModelStatePreserver.Awake] Created on " + ((Object)((Component)this).gameObject).name);
				Log.Info($"[ModelStatePreserver.Awake] EnableObjectPersistence: {PluginConfig.Instance.EnableObjectPersistence.Value}");
			}
			_modelLocator = ((Component)this).GetComponent<ModelLocator>();
			if ((Object)(object)_modelLocator != (Object)null && (Object)(object)_modelLocator.modelTransform != (Object)null)
			{
				originalAutoUpdateModelTransform = _modelLocator.autoUpdateModelTransform;
				originalInitialPosition = _modelLocator.modelTransform.localPosition;
				originalInitialRotation = _modelLocator.modelTransform.localRotation;
				originalInitialScale = _modelLocator.modelTransform.localScale;
				originalModelParent = _modelLocator.modelTransform.parent;
				if (PluginConfig.Instance.EnableDebugLogs.Value)
				{
					Log.Info("[ModelStatePreserver.Awake] Captured state for " + ((Object)((Component)this).gameObject).name);
					Log.Info($"[ModelStatePreserver.Awake] Original Position: {originalInitialPosition}");
					Log.Info($"[ModelStatePreserver.Awake] Original Rotation: {originalInitialRotation}");
					Log.Info($"[ModelStatePreserver.Awake] Original Scale: {originalInitialScale}");
				}
				rootRelativePosition = ((Component)this).transform.InverseTransformPoint(_modelLocator.modelTransform.position);
				rootRelativeRotation = Quaternion.Inverse(((Component)this).transform.rotation) * _modelLocator.modelTransform.rotation;
				Vector3 lossyScale = _modelLocator.modelTransform.lossyScale;
				Vector3 lossyScale2 = ((Component)this).transform.lossyScale;
				rootRelativeScale = new Vector3((lossyScale2.x != 0f) ? (lossyScale.x / lossyScale2.x) : lossyScale.x, (lossyScale2.y != 0f) ? (lossyScale.y / lossyScale2.y) : lossyScale.y, (lossyScale2.z != 0f) ? (lossyScale.z / lossyScale2.z) : lossyScale.z);
			}
			else if (PluginConfig.Instance.EnableDebugLogs.Value)
			{
				Log.Warning("[ModelStatePreserver.Awake] No ModelLocator or modelTransform found on " + ((Object)((Component)this).gameObject).name);
			}
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if ((Object)(object)val != (Object)null && !_rendererStates.ContainsKey(val))
				{
					_rendererStates[val] = val.enabled;
				}
			}
			Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Collider>(true);
			Collider[] array2 = componentsInChildren2;
			foreach (Collider val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && !_colliderStates.ContainsKey(val2))
				{
					_colliderStates[val2] = val2.enabled;
				}
			}
		}

		public void RestoreOriginalState(bool restoreParent = true)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.Instance.EnableDebugLogs.Value)
			{
				Log.Info($"[ModelStatePreserver.RestoreOriginalState] Called for {((Object)((Component)this).gameObject).name}, restoreParent: {restoreParent}");
			}
			if (!((Object)(object)_modelLocator != (Object)null) || !((Object)(object)_modelLocator.modelTransform != (Object)null))
			{
				return;
			}
			if (restoreParent)
			{
				_modelLocator.modelTransform.SetParent(originalModelParent, false);
				_modelLocator.modelTransform.localPosition = originalInitialPosition;
				_modelLocator.modelTransform.localRotation = originalInitialRotation;
				_modelLocator.modelTransform.localScale = originalInitialScale;
			}
			else if ((Object)(object)_modelLocator.modelTransform != (Object)(object)((Component)this).gameObject.transform)
			{
				_modelLocator.modelTransform.localPosition = rootRelativePosition;
				_modelLocator.modelTransform.localRotation = rootRelativeRotation;
				_modelLocator.modelTransform.localScale = rootRelativeScale;
			}
			else
			{
				_modelLocator.modelTransform.localScale = originalInitialScale;
			}
			_modelLocator.autoUpdateModelTransform = originalAutoUpdateModelTransform;
			foreach (KeyValuePair<Renderer, bool> rendererState in _rendererStates)
			{
				if ((Object)(object)rendererState.Key != (Object)null)
				{
					rendererState.Key.enabled = rendererState.Value;
				}
			}
			foreach (KeyValuePair<Collider, bool> colliderState in _colliderStates)
			{
				if ((Object)(object)colliderState.Key != (Object)null)
				{
					colliderState.Key.enabled = colliderState.Value;
				}
			}
		}

		private void OnDestroy()
		{
			if (PluginConfig.Instance.EnableDebugLogs.Value)
			{
				Log.Info("[ModelStatePreserver.OnDestroy] Destroyed on " + ((Object)((Component)this).gameObject).name);
			}
		}
	}
	public interface IPersistenceCommand
	{
		void Execute();

		void Undo();
	}
	public class AddPersistedObjectCommand : IPersistenceCommand
	{
		private readonly GameObject _obj;

		private readonly string? _ownerPlayerId;

		public AddPersistedObjectCommand(GameObject obj, string? ownerPlayerId = null)
		{
			_obj = obj;
			_ownerPlayerId = ownerPlayerId;
		}

		public void Execute()
		{
			PersistenceObjectManager.AddPersistedObjectInternal(_obj, _ownerPlayerId);
		}

		public void Undo()
		{
			PersistenceObjectManager.RemovePersistedObjectInternal(_obj);
		}
	}
	public class RemovePersistedObjectCommand : IPersistenceCommand
	{
		private readonly GameObject _obj;

		private readonly bool _isDestroying;

		public RemovePersistedObjectCommand(GameObject obj, bool isDestroying = false)
		{
			_obj = obj;
			_isDestroying = isDestroying;
		}

		public void Execute()
		{
			PersistenceObjectManager.RemovePersistedObjectInternal(_obj, _isDestroying);
		}

		public void Undo()
		{
			PersistenceObjectManager.AddPersistedObjectInternal(_obj);
		}
	}
	public class ClearPersistedObjectsCommand : IPersistenceCommand
	{
		private GameObject[] _clearedObjects;

		public void Execute()
		{
			_clearedObjects = PersistenceObjectManager.GetPersistedObjects();
			PersistenceObjectManager.ClearPersistedObjectsInternal();
		}

		public void Undo()
		{
			GameObject[] clearedObjects = _clearedObjects;
			foreach (GameObject val in clearedObjects)
			{
				if ((Object)(object)val != (Object)null)
				{
					PersistenceObjectManager.AddPersistedObjectInternal(val);
				}
			}
		}
	}
	public class PersistenceCommandInvoker
	{
		private readonly Stack<IPersistenceCommand> _commandHistory = new Stack<IPersistenceCommand>();

		public void ExecuteCommand(IPersistenceCommand command)
		{
			command.Execute();
			_commandHistory.Push(command);
		}

		public void UndoLastCommand()
		{
			if (_commandHistory.Count > 0)
			{
				IPersistenceCommand persistenceCommand = _commandHistory.Pop();
				persistenceCommand.Undo();
			}
		}

		public void ClearHistory()
		{
			_commandHistory.Clear();
		}

		public int GetHistoryCount()
		{
			return _commandHistory.Count;
		}
	}
	public static class PersistenceManager
	{
		private static readonly HashSet<GameObject> _teleportersToDisable = new HashSet<GameObject>();

		private static readonly object _teleporterLock = new object();

		public static void Initialize()
		{
			PersistenceObjectManager.Initialize();
		}

		public static void Cleanup()
		{
			PersistenceObjectManager.Cleanup();
		}

		public static void UpdateCachedConfig()
		{
			PersistenceObjectManager.UpdateCachedConfig();
		}

		public static void AddPersistedObject(GameObject obj)
		{
			PersistenceObjectManager.AddPersistedObject(obj);
		}

		public static void RemovePersistedObject(GameObject obj, bool isDestroying = false)
		{
			PersistenceObjectManager.RemovePersistedObject(obj, isDestroying);
		}

		public static void ClearPersistedObjects()
		{
			PersistenceObjectManager.ClearPersistedObjects();
		}

		public static void CaptureCurrentlyBaggedObjects()
		{
			PersistenceObjectManager.CaptureCurrentlyBaggedObjects();
		}

		public static List<GameObject> GetCurrentlyBaggedObjects()
		{
			return PersistenceObjectManager.GetCurrentlyBaggedObjects();
		}

		public static void MoveObjectsToPersistenceContainer()
		{
			PersistenceObjectManager.MoveObjectsToPersistenceContainer();
		}

		public static void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			PersistenceSceneHandler.Instance.OnSceneChanged(oldScene, newScene);
		}

		public static void ScheduleAutoGrab(CharacterMaster master)
		{
			PersistenceSceneHandler.Instance.ScheduleAutoGrab(master);
		}

		public static int GetPersistedObjectsCount()
		{
			return PersistenceObjectManager.GetPersistedObjectsCount();
		}

		public static GameObject[] GetPersistedObjects()
		{
			return PersistenceObjectManager.GetPersistedObjects();
		}

		public static void UndoLastCommand()
		{
			PersistenceObjectManager.UndoLastCommand();
		}

		public static int GetCommandHistoryCount()
		{
			return PersistenceObjectManager.GetCommandHistoryCount();
		}

		public static void ClearCommandHistory()
		{
			PersistenceObjectManager.ClearCommandHistory();
		}

		public static bool IsObjectPersisted(GameObject obj)
		{
			return PersistenceObjectManager.IsObjectPersisted(obj);
		}

		public static bool ShouldDisableTeleporter(GameObject obj)
		{
			lock (_teleporterLock)
			{
				return _teleportersToDisable.Contains(obj);
			}
		}

		public static void MarkTeleporterForDisabling(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return;
			}
			lock (_teleporterLock)
			{
				_teleportersToDisable.Add(obj);
				if (PluginConfig.Instance.EnableDebugLogs.Value)
				{
					Log.Info($" Marked {((Object)obj).name} for teleporter disabling, total marked: {_teleportersToDisable.Count}");
				}
			}
		}

		public static void ClearTeleporterDisablingMarks()
		{
			lock (_teleporterLock)
			{
				_teleportersToDisable.Clear();
			}
		}
	}
	public class PersistenceManagerWrapper : IConfigurable
	{
		public void Initialize()
		{
			PersistenceManager.Initialize();
		}

		public void Cleanup()
		{
			PersistenceManager.Cleanup();
		}
	}
	public static class PersistenceNetworkHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<Stage> <0>__OnServerStageComplete;

			public static NetworkMessageDelegate <1>__HandleUpdateBagStateMessage;

			public static NetworkMessageDelegate <2>__HandleBaggedObjectsPersistenceMessage;
		}

		[CompilerGenerated]
		private sealed class <RetryFindController>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UpdateBagStateMessage msg;

			private int <attempt>5__2;

			private int <frame>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RetryFindController>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					<frame>5__3++;
					goto IL_0053;
				}
				<>1__state = -1;
				<attempt>5__2 = 0;
				goto IL_00dd;
				IL_0053:
				if (<frame>5__3 < 10)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				GameObject val = ClientScene.FindLocalObject(msg.controllerNetId);
				if ((Object)(object)val != (Object)null)
				{
					if (PluginConfig.Instance.EnableDebugLogs.Value)
					{
						Log.Info($"[RetryFindController] Found controller object {((Object)val).name} (netId: {((NetworkInstanceId)(ref msg.controllerNetId)).Value}) after retry (attempt {<attempt>5__2 + 1})");
					}
					ApplyBagStateUpdate(val, msg);
					return false;
				}
				<attempt>5__2++;
				goto IL_00dd;
				IL_00dd:
				if (<attempt>5__2 < 10)
				{
					<frame>5__3 = 0;
					goto IL_0053;
				}
				Log.Error($"[RetryFindController] Failed to find controller object with netId {((NetworkInstanceId)(ref msg.controllerNetId)).Value} after 10 retries");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override