Decompiled source of CleanupSnatcher v1.0.2

plugins/com.pwdcat.CleanupSnatcher.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 EntityStates;
using EntityStates.Drifter;
using EntityStates.Drifter.Bag;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[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.CleanupSnatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("com.pwdcat.CleanupSnatcher")]
[assembly: AssemblyTitle("CleanupSnatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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 CleanupSnatcher
{
	internal static class Constants
	{
		public const string LogPrefix = "[CleanupSnatcher]";

		public const string PluginGuid = "pwdcat.CleanupSnatcher";

		public const string PluginName = "CleanupSnatcher";

		public const string PluginVersion = "1.0.0";
	}
	internal static class Log
	{
		private static ManualLogSource? _logSource;

		private const string ERROR_PREFIX = "[ERROR] ";

		private const string FATAL_PREFIX = "[FATAL] ";

		private const string INFO_PREFIX = "[INFO] ";

		private const string WARNING_PREFIX = "[WARNING] ";

		internal static bool EnableDebugLogs { get; set; }

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error(object data)
		{
			ManualLogSource? logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogMessage((object)("[ERROR] " + data));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal(object data)
		{
			ManualLogSource? logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogMessage((object)("[FATAL] " + data));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info(object data)
		{
			if (EnableDebugLogs)
			{
				ManualLogSource? logSource = _logSource;
				if (logSource != null)
				{
					logSource.LogMessage((object)("[INFO] " + data));
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message(object data)
		{
			ManualLogSource? logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogMessage(data);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning(object data)
		{
			ManualLogSource? logSource = _logSource;
			if (logSource != null)
			{
				logSource.LogMessage((object)("[WARNING] " + data));
			}
		}
	}
	[BepInPlugin("pwdcat.CleanupSnatcher", "CleanupSnatcher", "1.0.0")]
	public class CleanupSnatcherPlugin : BaseUnityPlugin
	{
		private EventHandler debugLogsHandler;

		private EventHandler projectileGrabbingHandler;

		public static CleanupSnatcherPlugin Instance { get; private set; }

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

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

		public void Awake()
		{
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Log.Info("[CleanupSnatcher] CleanupSnatcherPlugin.Awake() called");
			PluginConfig.Init(((BaseUnityPlugin)this).Config);
			Log.EnableDebugLogs = PluginConfig.EnableDebugLogs.Value;
			Log.Info(string.Format("{0} Debug logs enabled: {1}", "[CleanupSnatcher]", Log.EnableDebugLogs));
			SetupConfigurationEventHandlers();
			ApplyHarmonyPatches();
			RegisterGameEvents();
			Log.Info("[CleanupSnatcher] Plugin initialization complete");
		}

		public void OnDestroy()
		{
			PluginConfig.RemoveEventHandlers(debugLogsHandler, projectileGrabbingHandler);
		}

		public void Start()
		{
			SetupRiskOfOptions();
		}

		private void SetupConfigurationEventHandlers()
		{
			debugLogsHandler = delegate
			{
				Log.EnableDebugLogs = PluginConfig.EnableDebugLogs.Value;
			};
			PluginConfig.EnableDebugLogs.SettingChanged += debugLogsHandler;
			projectileGrabbingHandler = delegate
			{
			};
			PluginConfig.EnableProjectileGrabbing.SettingChanged += projectileGrabbingHandler;
		}

		private void ApplyHarmonyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Harmony val = new Harmony("pwdcat.CleanupSnatcher");
			val.PatchAll();
		}

		private void RegisterGameEvents()
		{
			SceneManager.activeSceneChanged += OnSceneChanged;
		}

		private static void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			if (PluginConfig.EnableDebugLogs.Value)
			{
				Log.Info("[CleanupSnatcher] Scene changed from " + ((Scene)(ref oldScene)).name + " to " + ((Scene)(ref newScene)).name);
			}
		}

		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 projectiles from their Cleanup ability.", "pwdcat.CleanupSnatcher", "CleanupSnatcher");
				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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (RooInstalled)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.EnableProjectileGrabbing));
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.EnableDebugLogs));
			}
		}
	}
	public static class PluginConfig
	{
		public static ConfigEntry<bool> EnableProjectileGrabbing { get; private set; }

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

		public static void Init(ConfigFile cfg)
		{
			EnableProjectileGrabbing = cfg.Bind<bool>("General", "EnableProjectileGrabbing", true, "Enable grabbing of projectiles from Drifter's Cleanup ability");
			EnableDebugLogs = cfg.Bind<bool>("General", "EnableDebugLogs", false, "Enable debug logging for projectile grabbing operations");
		}

		public static void RemoveEventHandlers(EventHandler debugLogsHandler, EventHandler projectileGrabbingHandler)
		{
			EnableDebugLogs.SettingChanged -= debugLogsHandler;
			EnableProjectileGrabbing.SettingChanged -= projectileGrabbingHandler;
		}
	}
}
namespace CleanupSnatcher.Patches
{
	public static class ProjectilePatches
	{
		[HarmonyPatch(typeof(DrifterCleanupController), "ToggleVisuals")]
		public class DrifterCleanupController_ToggleVisuals_Patch
		{
			[HarmonyPrefix]
			public static void Prefix(DrifterCleanupController __instance, GameObject target, bool enabled, float duration)
			{
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info(string.Format("{0} ToggleVisuals called - target: {1}, enabled: {2}, duration: {3}", "[CleanupSnatcher]", (target != null) ? ((Object)target).name : null, enabled, duration));
				}
				_isToggleVisualsDisplayActive = enabled;
				if (!enabled)
				{
					_shouldMakeNextProjectilesGrabbable = false;
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Display disabled - clearing grab flag");
					}
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileManager), "FireProjectileServer", new Type[]
		{
			typeof(FireProjectileInfo),
			typeof(NetworkConnection),
			typeof(ushort),
			typeof(double)
		})]
		public class ProjectileManager_FireProjectileServer_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(FireProjectileInfo fireProjectileInfo)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				if (PluginConfig.EnableDebugLogs.Value)
				{
					object[] obj = new object[4] { "[CleanupSnatcher]", null, null, null };
					GameObject projectilePrefab = fireProjectileInfo.projectilePrefab;
					obj[1] = ((projectilePrefab != null) ? ((Object)projectilePrefab).name : null);
					obj[2] = fireProjectileInfo.position;
					GameObject owner = fireProjectileInfo.owner;
					obj[3] = ((owner != null) ? ((Object)owner).name : null);
					Log.Info(string.Format("{0} ProjectileManager.FireProjectileServer - prefab: {1}, position: {2}, owner: {3}", obj));
				}
				if (PluginConfig.EnableProjectileGrabbing.Value && _shouldMakeNextProjectilesGrabbable)
				{
					if (PluginConfig.EnableDebugLogs.Value)
					{
						GameObject projectilePrefab2 = fireProjectileInfo.projectilePrefab;
						Log.Info("[CleanupSnatcher] ProjectileManager.FireProjectileServer - flag set for projectile: " + ((projectilePrefab2 != null) ? ((Object)projectilePrefab2).name : null));
					}
					_shouldMakeNextProjectilesGrabbable = false;
				}
			}
		}

		[HarmonyPatch(typeof(NetworkServer), "Spawn", new Type[] { typeof(GameObject) })]
		public class NetworkServer_Spawn_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(GameObject obj)
			{
				if (PluginConfig.EnableProjectileGrabbing.Value && _shouldMakeNextProjectilesGrabbable && !((Object)(object)obj == (Object)null) && (Object)(object)obj.GetComponent<ProjectileController>() != (Object)null)
				{
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] NetworkServer.Spawn - making projectile grabbable: " + ((Object)obj).name);
					}
					AddSpecialObjectAttributesToProjectile(obj);
					_activeProjectile = obj;
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Set active projectile: " + ((Object)obj).name);
					}
				}
			}
		}

		[HarmonyPatch(typeof(GenericSkill), "ExecuteIfReady")]
		public class GenericSkill_ExecuteIfReady_Patch
		{
			[HarmonyPrefix]
			public static bool Prefix(GenericSkill __instance, ref bool __result)
			{
				//IL_060a: Unknown result type (might be due to invalid IL or missing references)
				//IL_061b: Unknown result type (might be due to invalid IL or missing references)
				//IL_061d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0624: Unknown result type (might be due to invalid IL or missing references)
				//IL_0626: Unknown result type (might be due to invalid IL or missing references)
				//IL_062b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0630: Unknown result type (might be due to invalid IL or missing references)
				//IL_0661: Unknown result type (might be due to invalid IL or missing references)
				//IL_0677: Unknown result type (might be due to invalid IL or missing references)
				//IL_0679: Unknown result type (might be due to invalid IL or missing references)
				//IL_0680: Unknown result type (might be due to invalid IL or missing references)
				//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_048f: Unknown result type (might be due to invalid IL or missing references)
				//IL_049b: Unknown result type (might be due to invalid IL or missing references)
				//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_04af: Unknown result type (might be due to invalid IL or missing references)
				//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_04be: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0432: Unknown result type (might be due to invalid IL or missing references)
				//IL_0538: Unknown result type (might be due to invalid IL or missing references)
				//IL_053d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0541: Unknown result type (might be due to invalid IL or missing references)
				//IL_0546: Unknown result type (might be due to invalid IL or missing references)
				//IL_054a: Unknown result type (might be due to invalid IL or missing references)
				//IL_054f: Unknown result type (might be due to invalid IL or missing references)
				//IL_046f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0567: Unknown result type (might be due to invalid IL or missing references)
				//IL_056e: Unknown result type (might be due to invalid IL or missing references)
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info("[CleanupSnatcher] ExecuteIfReady called for skill: " + __instance.skillDef?.skillName);
				}
				if (!PluginConfig.EnableProjectileGrabbing.Value)
				{
					return true;
				}
				GameObject value;
				float value2;
				float value3;
				float value4;
				GameObject gameObject;
				Vector3 val5;
				Vector3 val6;
				if (__instance.skillDef?.skillName == "Repossess" && _isToggleVisualsDisplayActive)
				{
					if (!__instance.CanExecute())
					{
						if (PluginConfig.EnableDebugLogs.Value)
						{
							Log.Info("[CleanupSnatcher] Repossess pressed but skill is not ready (cooldown) - skipping projectile spawn");
						}
						return true;
					}
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Repossess pressed while ToggleVisuals display is ACTIVE - spawning projectile directly");
					}
					SkillLocator component = ((Component)__instance).GetComponent<SkillLocator>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.secondary != (Object)null)
					{
						GenericSkill secondary = component.secondary;
						EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)component).gameObject, "Bag");
						if ((Object)(object)val != (Object)null && val.state is BaggedObject)
						{
							if (PluginConfig.EnableDebugLogs.Value)
							{
								Log.Info("[CleanupSnatcher] Bag is already full, skipping projectile spawn");
							}
							return true;
						}
						DrifterCleanupController component2 = ((Component)component).gameObject.GetComponent<DrifterCleanupController>();
						if ((Object)(object)component2 != (Object)null)
						{
							if (PluginConfig.EnableDebugLogs.Value)
							{
								Log.Info("[CleanupSnatcher] Manually cycling projectile index in DrifterCleanupController");
							}
							FieldInfo field = typeof(DrifterCleanupController).GetField("prefabIndex", BindingFlags.Instance | BindingFlags.NonPublic);
							if (field != null)
							{
								try
								{
									FieldInfo field2 = typeof(DrifterCleanupController).GetField("projectileCandidateSelection", BindingFlags.Instance | BindingFlags.NonPublic);
									if (field2 != null)
									{
										if (field2.GetValue(component2) is WeightedSelection<Candidate> val2)
										{
											int num = (int)field.GetValue(component2);
											int num2 = Math.Abs(num);
											int num3 = (num2 + 1) % val2.Count;
											if (num < 0)
											{
												num3 = -num3;
											}
											field.SetValue(component2, num3);
											if (PluginConfig.EnableDebugLogs.Value)
											{
												Log.Info(string.Format("{0} Cycled prefabIndex from {1} to {2} (total candidates: {3})", "[CleanupSnatcher]", num, num3, val2.Count));
											}
										}
										else if (PluginConfig.EnableDebugLogs.Value)
										{
											Log.Info("[CleanupSnatcher] Could not get projectile candidate selection");
										}
									}
									else
									{
										int num4 = (int)field.GetValue(component2);
										int num5 = Math.Abs(num4);
										int num6 = (num5 + 1) % 3;
										if (num4 < 0)
										{
											num6 = -num6;
										}
										field.SetValue(component2, num6);
										if (PluginConfig.EnableDebugLogs.Value)
										{
											Log.Info(string.Format("{0} Fallback cycling prefabIndex from {1} to {2}", "[CleanupSnatcher]", num4, num6));
										}
									}
								}
								catch (Exception ex)
								{
									if (PluginConfig.EnableDebugLogs.Value)
									{
										Log.Info("[CleanupSnatcher] Failed to cycle prefabIndex: " + ex.Message);
									}
								}
							}
							else if (PluginConfig.EnableDebugLogs.Value)
							{
								Log.Info("[CleanupSnatcher] Could not find prefabIndex field in DrifterCleanupController");
							}
						}
						else if (PluginConfig.EnableDebugLogs.Value)
						{
							Log.Info("[CleanupSnatcher] Could not find DrifterCleanupController for manual cycling");
						}
						if ((Object)(object)secondary.stateMachine != (Object)null)
						{
							EntityState state = secondary.stateMachine.state;
							AimMagicBag val3 = (AimMagicBag)(object)((state is AimMagicBag) ? state : null);
							if (val3 != null)
							{
								Traverse val4 = Traverse.Create((object)val3);
								value = val4.Field("projectilePrefab").GetValue<GameObject>();
								if ((Object)(object)value != (Object)null)
								{
									if (PluginConfig.EnableDebugLogs.Value)
									{
										Log.Info("[CleanupSnatcher] Spawning cycled projectile: " + ((Object)value).name);
									}
									_shouldMakeNextProjectilesGrabbable = true;
									value2 = val4.Field("damageCoefficient").GetValue<float>();
									value3 = val4.Field("force").GetValue<float>();
									value4 = val4.Field("damageStat").GetValue<float>();
									gameObject = ((Component)component).gameObject;
									if (PluginConfig.EnableDebugLogs.Value)
									{
										Log.Info(string.Format("{0} Drifter position: {1}", "[CleanupSnatcher]", gameObject.transform.position));
										Log.Info(string.Format("{0} Drifter forward: {1}", "[CleanupSnatcher]", gameObject.transform.forward));
										Camera main = Camera.main;
										Log.Info(string.Format("{0} Camera position: {1}", "[CleanupSnatcher]", (main != null) ? new Vector3?(((Component)main).transform.position) : null));
										Camera main2 = Camera.main;
										Log.Info(string.Format("{0} Camera forward: {1}", "[CleanupSnatcher]", (main2 != null) ? new Vector3?(((Component)main2).transform.forward) : null));
									}
									val5 = gameObject.transform.position + gameObject.transform.forward * 2f + Vector3.up * 1f;
									val6 = gameObject.transform.forward;
									if ((Object)(object)secondary.stateMachine != (Object)null)
									{
										EntityState state2 = secondary.stateMachine.state;
										AimMagicBag val7 = (AimMagicBag)(object)((state2 is AimMagicBag) ? state2 : null);
										if (val7 != null)
										{
											Traverse val8 = Traverse.Create((object)val7);
											object value5 = val8.Field("currentTrajectoryInfo").GetValue();
											if (value5 != null)
											{
												try
												{
													Ray val9 = (Ray)value5.GetType().GetField("finalRay").GetValue(value5);
													val5 = ((Ray)(ref val9)).origin;
													val6 = ((Ray)(ref val9)).direction;
													if (PluginConfig.EnableDebugLogs.Value)
													{
														Log.Info(string.Format("{0} Using AimMagicBag trajectory - position: {1}, direction: {2}", "[CleanupSnatcher]", val5, val6));
													}
												}
												catch (Exception ex2)
												{
													if (PluginConfig.EnableDebugLogs.Value)
													{
														Log.Info("[CleanupSnatcher] Failed to get trajectory data: " + ex2.Message + ", using fallback");
													}
												}
											}
											else if (PluginConfig.EnableDebugLogs.Value)
											{
												Log.Info("[CleanupSnatcher] No trajectory info available, using fallback values");
											}
											goto IL_05da;
										}
									}
									if (PluginConfig.EnableDebugLogs.Value)
									{
										Log.Info("[CleanupSnatcher] Could not find AimMagicBag state, using fallback values");
									}
									goto IL_05da;
								}
								if (PluginConfig.EnableDebugLogs.Value)
								{
									Log.Info("[CleanupSnatcher] No projectile prefab found after Cleanup execution");
								}
								goto IL_06e5;
							}
						}
						if (PluginConfig.EnableDebugLogs.Value)
						{
							Log.Info("[CleanupSnatcher] Could not find AimMagicBag state after Cleanup execution");
						}
					}
					else if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Could not find SkillLocator or Cleanup skill");
					}
					goto IL_06e5;
				}
				return true;
				IL_05da:
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info(string.Format("{0} Final spawn position: {1}, direction: {2}", "[CleanupSnatcher]", val5, val6));
				}
				FireProjectileInfo val10 = default(FireProjectileInfo);
				val10.projectilePrefab = value;
				val10.position = val5;
				val10.rotation = Util.QuaternionSafeLookRotation(val6, Vector3.up);
				((FireProjectileInfo)(ref val10)).speedOverride = 0f;
				val10.damage = value2 * value4;
				val10.owner = gameObject;
				val10.crit = false;
				val10.damageColorIndex = (DamageColorIndex)0;
				val10.force = value3;
				val10.target = null;
				FireProjectileInfo val11 = val10;
				ProjectileManager.instance.FireProjectile(val11);
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info("[CleanupSnatcher] Cycled projectile spawned for Repossess grab");
				}
				goto IL_06e5;
				IL_06e5:
				return true;
			}
		}

		[HarmonyPatch(typeof(BaggedObject), "OnEnter")]
		public class BaggedObject_OnEnter_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(BaggedObject __instance)
			{
				if ((Object)(object)_activeProjectile != (Object)null)
				{
					Traverse val = Traverse.Create((object)__instance);
					GameObject value = val.Field("targetObject").GetValue<GameObject>();
					if ((Object)(object)value == (Object)(object)_activeProjectile)
					{
						Log.Info("[CleanupSnatcher] Active projectile grabbed: " + ((Object)_activeProjectile).name);
						_activeProjectile = null;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ThrownObjectProjectileController), "ImpactBehavior")]
		public class ThrownObjectProjectileController_ImpactBehavior_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(ThrownObjectProjectileController __instance)
			{
				if ((Object)(object)_activeProjectile != (Object)null && (Object)(object)((Component)__instance).gameObject == (Object)(object)_activeProjectile)
				{
					Log.Info("[CleanupSnatcher] Active projectile impacted: " + ((Object)_activeProjectile).name);
					_activeProjectile = null;
				}
			}
		}

		[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
		public class Object_Destroy_Patch
		{
			[HarmonyPrefix]
			public static void Prefix(Object obj)
			{
				if ((Object)(object)_activeProjectile != (Object)null)
				{
					GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
					if (val != null && (Object)(object)val == (Object)(object)_activeProjectile)
					{
						Log.Info("[CleanupSnatcher] Active projectile destroyed: " + ((Object)_activeProjectile).name);
						_activeProjectile = null;
					}
				}
			}
		}

		[HarmonyPatch(typeof(RepossessBullseyeSearch), "GetResults")]
		public class RepossessBullseyeSearch_GetResults_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(ref IEnumerable<GameObject> __result)
			{
				if ((Object)(object)_activeProjectile != (Object)null)
				{
					List<GameObject> list = new List<GameObject>(__result);
					if (!list.Contains(_activeProjectile))
					{
						list.Insert(0, _activeProjectile);
						Log.Info("[CleanupSnatcher] Force-added active projectile to repossess results: " + ((Object)_activeProjectile).name);
					}
					else
					{
						list.Remove(_activeProjectile);
						list.Insert(0, _activeProjectile);
						Log.Info("[CleanupSnatcher] Moved active projectile to front of repossess results: " + ((Object)_activeProjectile).name);
					}
					__result = list;
				}
			}
		}

		private static bool _shouldMakeNextProjectilesGrabbable;

		private static bool _isToggleVisualsDisplayActive;

		private static GameObject _activeProjectile;

		private static Texture GetProjectileIcon(string projectileName)
		{
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			string text = projectileName switch
			{
				"DrifterGrenade" => "RoR2/Base/StickyBomb/texStickyBombIcon.png", 
				"DrifterJunkBall" => "RoR2/DLC3/Items/texJunkIcon.png", 
				"DrifterToolbotCrate" => "RoR2/DLC3/Items/PowerCube/texPowerCubeIcon.png", 
				"DrifterHotSauce" => "RoR2/DLC1/Molotov/texMolotovIcon.png", 
				"DrifterKnife" => "RoR2/Base/Dagger/texDaggerIcon.png", 
				"DrifterBubbleShield" => "RoR2/Junk/Engi/texEngiShieldSpriteCrosshair.png", 
				"DrifterGeode" => "RoR2/DLC2/texAFUIChunkIcon.png", 
				"DrifterBarrel" => "RoR2/Base/Common/MiscIcons/texBarrelIcon.png", 
				"DrifterBrokenDrone" => "RoR2/Base/Drones/texDrone2Icon.png", 
				"DrifterBrokenHAND" => "RoR2/Base/Toolbot/texToolbotIcon.png", 
				"DrifterEvilSkull" => "RoR2/Base/AltarSkeleton/texAltarSkeletonBody.png", 
				_ => "RoR2/Base/Common/MiscIcons/texMysteryIcon.png", 
			};
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					Texture2D val = Addressables.LoadAssetAsync<Texture2D>((object)text).WaitForCompletion();
					if ((Object)(object)val != (Object)null)
					{
						if (PluginConfig.EnableDebugLogs.Value)
						{
							Log.Info("[CleanupSnatcher] Loaded icon via Addressables: " + text);
						}
						return (Texture)(object)val;
					}
				}
				catch (Exception ex)
				{
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Failed to load via Addressables " + text + ": " + ex.Message + ", falling back to LegacyResourcesAPI");
					}
				}
			}
			return null;
		}

		private static void AddSpecialObjectAttributesToProjectile(GameObject obj)
		{
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)obj == (Object)null)
			{
				return;
			}
			string text = ((Object)obj).name;
			string text2 = text.ToLowerInvariant();
			if (string.IsNullOrEmpty(text))
			{
				string text4 = (((Object)obj).name = "Projectile_" + ((Object)obj).GetInstanceID());
				text = text4;
				text2 = text.ToLowerInvariant();
			}
			if (PluginConfig.EnableDebugLogs.Value)
			{
				Log.Info("[CleanupSnatcher] Using projectile object " + ((Object)obj).name + " for SpecialObjectAttributes (original: " + text + ")");
			}
			NetworkIdentity component = obj.GetComponent<NetworkIdentity>();
			if ((Object)(object)component != (Object)null)
			{
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info(string.Format("{0} Target {1} already has NetworkIdentity: netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
				}
			}
			else
			{
				component = obj.AddComponent<NetworkIdentity>();
				component.serverOnly = false;
				component.localPlayerAuthority = false;
				try
				{
					if (NetworkServer.active)
					{
						NetworkServer.Spawn(obj);
						if (PluginConfig.EnableDebugLogs.Value)
						{
							Log.Info(string.Format("{0} Successfully spawned projectile {1} on network with netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
						}
					}
					else if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] NetworkServer not active, cannot spawn projectile " + ((Object)obj).name);
					}
				}
				catch (Exception ex)
				{
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Failed to spawn projectile " + ((Object)obj).name + " on network: " + ex.Message);
					}
				}
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info(string.Format("{0} Added NetworkIdentity to projectile {1}: netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
				}
			}
			SpecialObjectAttributes component2 = obj.GetComponent<SpecialObjectAttributes>();
			if ((Object)(object)component2 != (Object)null)
			{
				if (!component2.grabbable || string.IsNullOrEmpty(component2.breakoutStateMachineName))
				{
					component2.grabbable = true;
					component2.breakoutStateMachineName = "";
					component2.orientToFloor = true;
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Updated existing SpecialObjectAttributes on projectile " + ((Object)obj).name);
					}
				}
				return;
			}
			SpecialObjectAttributes val = obj.AddComponent<SpecialObjectAttributes>();
			val.renderersToDisable = new List<Renderer>();
			val.behavioursToDisable = new List<MonoBehaviour>();
			val.collisionToDisable = new List<GameObject>();
			val.childObjectsToDisable = new List<GameObject>();
			val.pickupDisplaysToDisable = new List<PickupDisplay>();
			val.lightsToDisable = new List<Light>();
			val.objectsToDetach = new List<GameObject>();
			val.childSpecialObjectAttributes = new List<SpecialObjectAttributes>();
			val.skillHighlightRenderers = new List<Renderer>();
			val.soundEventsToStop = new List<AkEvent>();
			val.soundEventsToPlay = new List<AkEvent>();
			(float massOverride, int maxDurability) tuple = CalculateScaledAttributes(obj, text);
			float item = tuple.massOverride;
			int item2 = tuple.maxDurability;
			val.grabbable = true;
			val.massOverride = item;
			val.maxDurability = item2;
			val.durability = item2;
			val.hullClassification = (HullClassification)0;
			val.breakoutStateMachineName = "";
			val.orientToFloor = true;
			string input = text.Replace("(Clone)", "");
			Regex regex = new Regex("\\s*\\(\\d+\\)$");
			input = (val.bestName = regex.Replace(input, ""));
			val.isVoid = text2.Contains("void");
			if (PluginConfig.EnableDebugLogs.Value && val.isVoid)
			{
				Log.Info("[CleanupSnatcher] Marked projectile " + text + " as void object");
			}
			val.portraitIcon = GetProjectileIcon(input);
			if (PluginConfig.EnableDebugLogs.Value && (Object)(object)val.portraitIcon != (Object)null)
			{
				Log.Info("[CleanupSnatcher] Set icon for projectile " + text);
			}
			Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(false);
			Renderer[] array = componentsInChildren;
			foreach (Renderer item3 in array)
			{
				val.renderersToDisable.Add(item3);
			}
			Collider[] componentsInChildren2 = obj.GetComponentsInChildren<Collider>(false);
			Collider[] array2 = componentsInChildren2;
			foreach (Collider val2 in array2)
			{
				val.collisionToDisable.Add(((Component)val2).gameObject);
			}
			Light[] componentsInChildren3 = obj.GetComponentsInChildren<Light>(false);
			Light[] array3 = componentsInChildren3;
			foreach (Light item4 in array3)
			{
				val.lightsToDisable.Add(item4);
			}
			PickupDisplay[] componentsInChildren4 = obj.GetComponentsInChildren<PickupDisplay>(false);
			PickupDisplay[] array4 = componentsInChildren4;
			foreach (PickupDisplay item5 in array4)
			{
				val.pickupDisplaysToDisable.Add(item5);
			}
			MonoBehaviour[] componentsInChildren5 = obj.GetComponentsInChildren<MonoBehaviour>(true);
			MonoBehaviour[] array5 = componentsInChildren5;
			foreach (MonoBehaviour val3 in array5)
			{
				if ((Object)(object)val3 == (Object)null || !((Behaviour)val3).enabled)
				{
					continue;
				}
				Type type = ((object)val3).GetType();
				if (!(type == typeof(NetworkIdentity)) && !(type == typeof(SpecialObjectAttributes)) && !(type == typeof(CharacterBody)))
				{
					val.behavioursToDisable.Add(val3);
					if (PluginConfig.EnableDebugLogs.Value)
					{
						Log.Info("[CleanupSnatcher] Disabled behavior: " + type.Name + " on " + text);
					}
				}
			}
			CharacterBody component3 = obj.GetComponent<CharacterBody>();
			if (!((Object)(object)component3 != (Object)null))
			{
				return;
			}
			try
			{
				component3.bodyFlags = (BodyFlags)(component3.bodyFlags & -524289);
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info("[CleanupSnatcher] Cleared Ungrabbable flag on CharacterBody for projectile " + text);
				}
			}
			catch (Exception ex2)
			{
				if (PluginConfig.EnableDebugLogs.Value)
				{
					Log.Info("[CleanupSnatcher] Failed to clear Ungrabbable flag on CharacterBody for projectile " + text + ": " + ex2.Message);
				}
			}
		}

		private static (float massOverride, int maxDurability) CalculateScaledAttributes(GameObject obj, string objName)
		{
			float num = CalculateObjectSizeMetric(obj);
			float num2 = Mathf.Clamp(num / 10f, 0.5f, 5f);
			float num3 = 100f * num2;
			int num4 = Mathf.RoundToInt(8f * num2);
			num3 = Mathf.Max(num3, 25f);
			num4 = Mathf.Max(num4, 3);
			if (PluginConfig.EnableDebugLogs.Value)
			{
				Log.Info(string.Format("{0} Size scaling for {1}: sizeMetric={2:F2}, scaleFactor={3:F2}, mass={4:F0}, durability={5}", "[CleanupSnatcher]", objName, num, num2, num3, num4));
			}
			return (num3, num4);
		}

		private static float CalculateObjectSizeMetric(GameObject obj)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)obj == (Object)null)
			{
				return 1f;
			}
			float num = 0f;
			Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(false);
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null || !val.enabled)
				{
					continue;
				}
				BoxCollider val2 = (BoxCollider)(object)((val is BoxCollider) ? val : null);
				if (val2 != null)
				{
					Vector3 size = val2.size;
					num += size.x * size.y * size.z;
					continue;
				}
				SphereCollider val3 = (SphereCollider)(object)((val is SphereCollider) ? val : null);
				if (val3 != null)
				{
					float radius = val3.radius;
					num += 4.1887903f * radius * radius * radius;
					continue;
				}
				CapsuleCollider val4 = (CapsuleCollider)(object)((val is CapsuleCollider) ? val : null);
				if (val4 != null)
				{
					float radius2 = val4.radius;
					float height = val4.height;
					num += MathF.PI * radius2 * radius2 * height;
					continue;
				}
				MeshCollider val5 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
				if (val5 != null)
				{
					Bounds bounds = ((Collider)val5).bounds;
					num += ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y * ((Bounds)(ref bounds)).size.z;
				}
			}
			return Mathf.Max(num, 0.1f);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}