Decompiled source of DrifterBossGrab v1.6.10
plugins/com.pwdcat.DrifterBossGrab.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
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