Decompiled source of H3TVR v2.0.6

H3TVR.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Valve.VR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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;
		}
	}
}
namespace H3TVR
{
	public class AirdropManager : MonoBehaviour
	{
		private H3TVRImproved plugin;

		private ManualLogSource logger;

		private const string CrateId = "Crate_Wood_1";

		private const float SpawnHeight = 40f;

		private const float ParachuteSlowdown = 0.2f;

		public void Initialize(H3TVRImproved pluginInstance, ManualLogSource logSource)
		{
			plugin = pluginInstance;
			logger = logSource;
			ManualLogSource obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)"Airdrop Manager initialized.");
			}
		}

		public void CallAirdrop(string username)
		{
			ManualLogSource obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)("Airdrop called in by " + username + "!"));
			}
			((MonoBehaviour)this).StartCoroutine(AirdropSequence());
		}

		private IEnumerator AirdropSequence()
		{
			if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
			{
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogError((object)"Cannot start airdrop: Player body not found.");
				}
				yield break;
			}
			Vector3 spawnPos = ((Component)GM.CurrentPlayerBody).transform.position + Vector3.up * 40f;
			if (!IM.OD.ContainsKey("Crate_Wood_1"))
			{
				ManualLogSource obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogError((object)"Cannot start airdrop: Crate template 'Crate_Wood_1' not found.");
				}
				yield break;
			}
			FVRObject crateTemplate = IM.OD["Crate_Wood_1"];
			GameObject crateGO = Object.Instantiate<GameObject>(((AnvilAsset)crateTemplate).GetGameObject(), spawnPos, Quaternion.identity);
			Rigidbody rb = crateGO.GetComponent<Rigidbody>();
			if ((Object)(object)rb == (Object)null)
			{
				ManualLogSource obj3 = logger;
				if (obj3 != null)
				{
					obj3.LogError((object)"Airdrop crate has no Rigidbody!");
				}
				Object.Destroy((Object)(object)crateGO);
				yield break;
			}
			rb.drag = 0.2f;
			bool isHelpful = Random.value < 0.7f;
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)crateGO == (Object)null || crateGO.transform.position.y < ((Component)GM.CurrentPlayerBody).transform.position.y + 2f));
			if ((Object)(object)crateGO != (Object)null)
			{
				PopulateCrate(crateGO.transform.position, isHelpful);
				crateGO.SendMessage("Damage", (object)1000f, (SendMessageOptions)1);
				ManualLogSource obj4 = logger;
				if (obj4 != null)
				{
					obj4.LogInfo((object)"Airdrop has landed!");
				}
			}
		}

		private void PopulateCrate(Vector3 position, bool isHelpful)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			if (isHelpful)
			{
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogInfo((object)"Airdrop is... HELPFUL!");
				}
				SpawnRandomHelpfulItem(position);
				SpawnItem("Health_Sausage", position + Vector3.up * 0.1f);
			}
			else
			{
				ManualLogSource obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogInfo((object)"Airdrop is... a TROLL!");
				}
				SpawnItem("PinnedGrenadeM67", position);
			}
		}

		private void SpawnRandomHelpfulItem(Vector3 position)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[3] { "MeatBatBaseball", "Health_Sausage", "SuppressorBottle" };
			string itemId = array[Random.Range(0, array.Length)];
			SpawnItem(itemId, position);
		}

		private void SpawnItem(string itemId, Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (IM.OD.ContainsKey(itemId))
				{
					FVRObject val = IM.OD[itemId];
					Object.Instantiate<GameObject>(((AnvilAsset)val).GetGameObject(), position, Quaternion.identity);
					return;
				}
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)("Item '" + itemId + "' not found in ObjectDictionary"));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogError((object)("Failed to spawn item '" + itemId + "': " + ex.Message));
				}
			}
		}
	}
	public class ConfigurationManager
	{
		private readonly ConfigFile config;

		private readonly ManualLogSource logger;

		private float cachedMaxSlomo;

		private float cachedSlomoWaitTime;

		private float cachedSlomoScaleSpeed;

		private float cachedSlomoReturnSpeed;

		private bool cachedSlomoUseRamp;

		private string cachedSlomoRampCurve;

		private float cachedSlomoRampDuration;

		private float cachedSlomoReturnRampDuration;

		private bool cachedEnableInfiniteTokens;

		private bool cachedDisableEncryptionNodes;

		private bool cachedDisableAllEncryptions;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public Dictionary<string, ConfigEntry<KeyCode>> KeyBindings { get; private set; } = new Dictionary<string, ConfigEntry<KeyCode>>();

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

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

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

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

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

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

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

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

		public float CachedMaxSlomo => cachedMaxSlomo;

		public float CachedSlomoWaitTime => cachedSlomoWaitTime;

		public float CachedSlomoScaleSpeed => cachedSlomoScaleSpeed;

		public float CachedSlomoReturnSpeed => cachedSlomoReturnSpeed;

		public bool CachedSlomoUseRamp => cachedSlomoUseRamp;

		public string CachedSlomoRampCurve => cachedSlomoRampCurve;

		public float CachedSlomoRampDuration => cachedSlomoRampDuration;

		public float CachedSlomoReturnRampDuration => cachedSlomoReturnRampDuration;

		public bool CachedSlomoAffectsAudio => true;

		public float CachedSlomoAudioPitchScale => 1f;

		public bool CachedSlomoAudioPreservePitch => false;

		public bool CachedSlomoAffectsAudioSpeed => false;

		public float CachedSlomoAudioSpeedScale => 1f;

		public string CachedSlomoAudioMode => "Both";

		public bool CachedEnableInfiniteTokens => cachedEnableInfiniteTokens;

		public bool CachedDisableEncryptionNodes => cachedDisableEncryptionNodes;

		public bool CachedDisableAllEncryptions => cachedDisableAllEncryptions;

		public ConfigurationManager(ConfigFile configFile, ManualLogSource logSource)
		{
			config = configFile;
			logger = logSource;
		}

		public void InitializeAll()
		{
			InitializeSlomoConfig();
			InitializeGunRandomizationConfig();
			InitializeSpawnConfigurations();
			InitializeKeyBindings();
			logger.LogInfo((object)"ConfigurationManager: All configuration entries initialized");
		}

		private void InitializeSlomoConfig()
		{
			MaxSlomo = config.Bind<float>("Slomo", "MaxSlowmoScale", 0.1f, "Maximum slomo scale (0.01 = 1% speed, 0.1 = 10% speed)");
			SlomoWaitTime = config.Bind<float>("Slomo", "WaitTime", 2f, "Time to wait at max slomo before returning to normal speed");
			SlomoScaleSpeed = config.Bind<float>("Slomo", "ScaleDownSpeed", 1f, "Speed at which time slows down (higher = faster transition)");
			SlomoReturnSpeed = config.Bind<float>("Slomo", "ReturnSpeed", 0.33f, "Speed at which time returns to normal (higher = faster return)");
			SlomoVRControllerEnabled = config.Bind<bool>("Slomo", "VRControllerEnabled", true, "Enable VR controller button to trigger slomo");
			SlomoVRButton = config.Bind<string>("Slomo", "VRButton", "LeftX", "VR button to trigger slomo");
			SlomoAffectsMovement = config.Bind<bool>("Slomo", "AffectsMovement", true, "Whether slomo affects player movement speed");
			SlomoMovementScale = config.Bind<float>("Slomo", "MovementScale", 0.3f, "Movement speed multiplier during slomo");
			SlomoUseRampSpeed = config.Bind<bool>("Slomo.Ramp", "UseRampSpeed", true, "Enable smooth ramp speed transitions for slomo (more cinematic)");
			SlomoRampCurve = config.Bind<string>("Slomo.Ramp", "RampCurve", "EaseInOut", "Curve type for slomo ramp: Linear, EaseIn, EaseOut, EaseInOut, Smooth, Cinematic");
			SlomoRampDuration = config.Bind<float>("Slomo.Ramp", "RampDuration", 0.5f, "Duration in seconds for slomo to ramp down to max slow speed");
			SlomoReturnRampDuration = config.Bind<float>("Slomo.Ramp", "ReturnRampDuration", 0.8f, "Duration in seconds for slomo to ramp back to normal speed");
			EnableKillSlomo = config.Bind<bool>("Slomo", "EnableKillSlomo", true, "Enable slow motion effect on enemy kill.");
		}

		private void InitializeGunRandomizationConfig()
		{
			UseItemManagerForGunRandomization = config.Bind<bool>("GunRandomization", "UseItemManager", true, "Use ItemManager for gun randomization (includes all H3VR and modded guns). If false, uses GunList/MagazineList config files.");
			GunList = config.Bind<string>("General", "GunList", "DefaultGunList", "List of guns");
			MagazineList = config.Bind<string>("General", "MagazineList", "DefaultMagazineList", "List of magazines");
		}

		private void InitializeSpawnConfigurations()
		{
			ShurikenScale = config.Bind<float>("Shuriken", "Scale", 1f, "Scale multiplier for spawned shuriken");
			ShurikenMinCount = config.Bind<int>("Shuriken", "MinCount", 1, "Minimum number of shuriken to spawn");
			ShurikenMaxCount = config.Bind<int>("Shuriken", "MaxCount", 3, "Maximum number of shuriken to spawn");
			PillowMinCount = config.Bind<int>("Pillow", "MinCount", 1, "Minimum number of pillows to spawn");
			PillowMaxCount = config.Bind<int>("Pillow", "MaxCount", 3, "Maximum number of pillows to spawn");
			PillowGrenadeEnabled = config.Bind<bool>("Pillow", "GrenadeEnabled", true, "Enable pillow grenade effect");
			PillowGrenadeChance = config.Bind<float>("Pillow", "GrenadeChance", 0.1f, "Chance for pillow to spawn grenade");
			PillowGrenadeArmedChance = config.Bind<float>("Pillow", "GrenadeArmedChance", 0.3f, "Chance for pillow grenade to be armed");
			PillowZeroGravityEnabled = config.Bind<bool>("Pillow", "ZeroGEnabled", true, "Enable pillow zero gravity effect");
			PillowZeroGravityChance = config.Bind<float>("Pillow", "ZeroGChance", 0.15f, "Chance for pillow to trigger zero gravity");
			PillowZeroGravityDuration = config.Bind<float>("Pillow", "ZeroGDuration", 10f, "Duration of pillow zero gravity effect");
			PillowSlomoEnabled = config.Bind<bool>("Pillow", "SlomoEnabled", true, "Enable pillow slow motion effect");
			PillowSlomoChance = config.Bind<float>("Pillow", "SlomoChance", 0.2f, "Chance for pillow to trigger slow motion");
			PillowSlomoDuration = config.Bind<float>("Pillow", "SlomoDuration", 8f, "Duration of pillow slow motion effect");
			DangerCloseMinCount = config.Bind<int>("DangerClose", "MinCount", 1, "Minimum danger close rounds");
			DangerCloseMaxCount = config.Bind<int>("DangerClose", "MaxCount", 5, "Maximum danger close rounds");
			EnableInfiniteTokens = config.Bind<bool>("TakeAndHold", "InfiniteTokens", false, "Enable infinite tokens in Take and Hold mode");
			DisableEncryptionNodes = config.Bind<bool>("TakeAndHold", "DisableEncryptionNodes", false, "Disable encryption nodes in Take and Hold mode for easier gameplay");
			DisableAllEncryptions = config.Bind<bool>("TakeAndHold.Encryption", "DisableAllEncryptions", false, "Master switch: Disable ALL encryption nodes (overrides specific settings)");
			DisableEncryptionType1 = config.Bind<bool>("TakeAndHold.Encryption", "DisableType1", false, "Disable Type 1 encryption nodes (pattern matching)");
			DisableEncryptionType2 = config.Bind<bool>("TakeAndHold.Encryption", "DisableType2", false, "Disable Type 2 encryption nodes (sequence)");
			DisableEncryptionType3 = config.Bind<bool>("TakeAndHold.Encryption", "DisableType3", false, "Disable Type 3 encryption nodes (timed)");
			AutoCompleteEncryption = config.Bind<bool>("TakeAndHold.Encryption", "AutoComplete", false, "Automatically complete enabled encryption nodes after delay");
			EncryptionCompletionDelay = config.Bind<float>("TakeAndHold.Encryption", "CompletionDelay", 2f, "Delay in seconds before auto-completing encryption (if AutoComplete enabled)");
		}

		private void InitializeKeyBindings()
		{
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, KeyValuePair<KeyCode, string>> dictionary = new Dictionary<string, KeyValuePair<KeyCode, string>>
			{
				{
					"SpawnWonderfulToy",
					new KeyValuePair<KeyCode, string>((KeyCode)257, "Spawn Wonderful Toy")
				},
				{
					"SpawnJeditToy",
					new KeyValuePair<KeyCode, string>((KeyCode)258, "Spawn Jedit Toy")
				},
				{
					"SpawnHydration",
					new KeyValuePair<KeyCode, string>((KeyCode)259, "Spawn Hydration")
				},
				{
					"SpawnPillow",
					new KeyValuePair<KeyCode, string>((KeyCode)260, "Spawn Pillow")
				},
				{
					"SpawnShuri",
					new KeyValuePair<KeyCode, string>((KeyCode)261, "Spawn Shuriken")
				},
				{
					"SpawnFlash",
					new KeyValuePair<KeyCode, string>((KeyCode)262, "Spawn Flash")
				},
				{
					"SpawnFlash2",
					new KeyValuePair<KeyCode, string>((KeyCode)263, "Spawn Flash2")
				},
				{
					"SpawnSkittySubGun",
					new KeyValuePair<KeyCode, string>((KeyCode)264, "Spawn Random Gun (Small)")
				},
				{
					"SpawnSkittyBigGun",
					new KeyValuePair<KeyCode, string>((KeyCode)265, "Spawn Random Gun (Large)")
				},
				{
					"SpawnNadeRain",
					new KeyValuePair<KeyCode, string>((KeyCode)267, "Spawn Grenade Rain")
				},
				{
					"DangerCloseBarrage",
					new KeyValuePair<KeyCode, string>((KeyCode)268, "Danger Close Barrage")
				},
				{
					"DestroyHeld",
					new KeyValuePair<KeyCode, string>((KeyCode)269, "Destroy Held Item")
				},
				{
					"DestroyQuickbelt",
					new KeyValuePair<KeyCode, string>((KeyCode)270, "Drop Quickbelt Items")
				},
				{
					"TriggerSlomo",
					new KeyValuePair<KeyCode, string>((KeyCode)102, "Trigger Slow Motion")
				},
				{
					"TriggerZeroG",
					new KeyValuePair<KeyCode, string>((KeyCode)103, "Trigger Zero Gravity")
				},
				{
					"ToggleFireMode",
					new KeyValuePair<KeyCode, string>((KeyCode)116, "Toggle Fire Mode")
				},
				{
					"BoostMalfunction",
					new KeyValuePair<KeyCode, string>((KeyCode)121, "Boost Malfunction")
				},
				{
					"ShowStats",
					new KeyValuePair<KeyCode, string>((KeyCode)9, "Show Stats")
				},
				{
					"SpawnAirStrike",
					new KeyValuePair<KeyCode, string>((KeyCode)291, "Spawn Air Strike Smoke Grenade")
				},
				{
					"SpawnTitanMachine",
					new KeyValuePair<KeyCode, string>((KeyCode)292, "Spawn Titan Machine (AI Enemy)")
				},
				{
					"SpawnNuke",
					new KeyValuePair<KeyCode, string>((KeyCode)110, "Spawn Nuke (Massive Explosion)")
				},
				{
					"EmptyHeldGunChamber",
					new KeyValuePair<KeyCode, string>((KeyCode)101, "Empty Held Gun Chamber")
				},
				{
					"SwapHeldGun",
					new KeyValuePair<KeyCode, string>((KeyCode)293, "Swap Held Gun for Random Gun")
				}
			};
			foreach (KeyValuePair<string, KeyValuePair<KeyCode, string>> item in dictionary)
			{
				KeyBindings[item.Key] = config.Bind<KeyCode>("KeyBindings", "KeyBindFor" + item.Key, item.Value.Key, item.Value.Value);
			}
		}

		public void RefreshCachedValues()
		{
			cachedMaxSlomo = MaxSlomo.Value;
			cachedSlomoWaitTime = SlomoWaitTime.Value;
			cachedSlomoScaleSpeed = SlomoScaleSpeed.Value;
			cachedSlomoReturnSpeed = SlomoReturnSpeed.Value;
			cachedSlomoUseRamp = SlomoUseRampSpeed.Value;
			cachedSlomoRampCurve = SlomoRampCurve.Value;
			cachedSlomoRampDuration = SlomoRampDuration.Value;
			cachedSlomoReturnRampDuration = SlomoReturnRampDuration.Value;
			cachedEnableInfiniteTokens = EnableInfiniteTokens.Value;
			cachedDisableEncryptionNodes = DisableEncryptionNodes.Value;
			cachedDisableAllEncryptions = DisableAllEncryptions.Value;
		}
	}
	[BepInPlugin("com.MrBeam.h3tvr", "H3TVR", "1.1.4")]
	[BepInProcess("h3vr.exe")]
	public class H3TVRImproved : BaseUnityPlugin
	{
		private enum EncryptionType
		{
			Unknown,
			Pattern,
			Sequence,
			Timed
		}

		private const float SlowdownFactor = 0.001f;

		private const float SlowdownLength = 6f;

		private const float ZeroGWaitTime = 6f;

		private const float RealisticFallTime = 1f;

		private const float MalfunctionBoostDuration = 120f;

		private const float ForcedMalfunctionChance = 0.75f;

		private string slomoStatus = "Off";

		private string zeroGStatus = "Off";

		private bool malfunctionBoostActive;

		private float malfunctionBoostEndTime;

		private float slomoRampStartTime;

		private float slomoRampStartValue;

		private bool isRamping;

		private ConfigEntry<float> maxSlomo;

		private ConfigEntry<float> slomoWaitTime;

		private ConfigEntry<float> slomoScaleSpeed;

		private ConfigEntry<float> slomoReturnSpeed;

		private ConfigEntry<bool> slomoVRControllerEnabled;

		private ConfigEntry<string> slomoVRButton;

		private ConfigEntry<bool> slomoAffectsMovement;

		private ConfigEntry<float> slomoMovementScale;

		private ConfigEntry<bool> slomoUseRampSpeed;

		private ConfigEntry<string> slomoRampCurve;

		private ConfigEntry<float> slomoRampDuration;

		private ConfigEntry<float> slomoReturnRampDuration;

		private ConfigEntry<bool> enableKillSlomo;

		private const bool slomoAffectsAudio = true;

		private const float slomoAudioPitchScale = 1f;

		private const bool slomoAudioPreservePitch = false;

		private const bool slomoAffectsAudioSpeed = false;

		private const float slomoAudioSpeedScale = 1f;

		private const string slomoAudioMode = "Both";

		private ConfigEntry<bool> useItemManagerForGunRandomization;

		private ConfigEntry<string> gunList;

		private ConfigEntry<string> magazineList;

		private ConfigEntry<float> shurikenScale;

		private ConfigEntry<int> shurikenMinCount;

		private ConfigEntry<int> shurikenMaxCount;

		private ConfigEntry<int> pillowMinCount;

		private ConfigEntry<int> pillowMaxCount;

		private ConfigEntry<bool> pillowGrenadeEnabled;

		private ConfigEntry<float> pillowGrenadeChance;

		private ConfigEntry<float> pillowGrenadeArmedChance;

		private ConfigEntry<bool> pillowZeroGravityEnabled;

		private ConfigEntry<float> pillowZeroGravityChance;

		private ConfigEntry<float> pillowZeroGravityDuration;

		private ConfigEntry<bool> pillowSlomoEnabled;

		private ConfigEntry<float> pillowSlomoChance;

		private ConfigEntry<float> pillowSlomoDuration;

		private ConfigEntry<int> dangerCloseMinCount;

		private ConfigEntry<int> dangerCloseMaxCount;

		private ConfigEntry<int> airStrikeGrenadeCount;

		private ConfigEntry<float> airStrikePinPullChance;

		private readonly Dictionary<string, ConfigEntry<KeyCode>> keyBindings = new Dictionary<string, ConfigEntry<KeyCode>>();

		private ConfigEntry<bool> enableInfiniteTokens;

		private ConfigEntry<bool> disableEncryptionNodes;

		private ConfigEntry<bool> disableAllEncryptions;

		private ConfigEntry<bool> disableEncryptionType1;

		private ConfigEntry<bool> disableEncryptionType2;

		private ConfigEntry<bool> disableEncryptionType3;

		private ConfigEntry<bool> autoCompleteEncryption;

		private ConfigEntry<float> encryptionCompletionDelay;

		private SlomoMovementController slomoMovementController;

		private readonly Hooks hooks = new Hooks();

		private InputHandler inputHandler;

		private SpawnManager spawnManager;

		private EffectsManager effectsManager;

		private WeaponManager weaponManager;

		private AudioManager audioManager;

		private AirdropManager airdropManager;

		private static Dictionary<AudioSource, float> originalAudioSpeeds = new Dictionary<AudioSource, float>();

		public H3TVRImproved()
		{
			hooks.Hook();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading H3TVR Enhanced Edition (Standalone Mode)");
		}

		private void Awake()
		{
			try
			{
				OptionalDependencyManager.Initialize(((BaseUnityPlugin)this).Logger);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"H3TVR Enhanced Edition (Standalone Mode) is loading...");
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 1: Initializing configuration...");
				InitializeConfiguration();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 2: Initializing optional dependencies...");
				InitializeOptionalDependencies();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 3: Initializing components...");
				InitializeComponents();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 3.6: Initializing Airdrop Manager...");
				InitializeAirdropManager();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 5: Initializing SpawnManager...");
				if ((Object)(object)spawnManager != (Object)null)
				{
					spawnManager.Initialize(this, ((BaseUnityPlugin)this).Logger, audioManager);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"SpawnManager initialized successfully");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)$"Cannot initialize SpawnManager - spawnManager: {(Object)(object)spawnManager != (Object)null}");
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Step 6: Initializing Twitch integration...");
				InitializeTwitchIntegration();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"H3TVR Enhanced Edition loaded successfully!");
				((BaseUnityPlugin)this).Logger.LogInfo((object)OptionalDependencyManager.GetDependencyStatusReport());
				if (MeatyceiverIntegrationManager.IsIntegrationEnabled())
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Meatyceiver 2 Integration: ACTIVE");
					((BaseUnityPlugin)this).Logger.LogInfo((object)MeatyceiverIntegrationManager.GetTransformationStats());
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Error during H3TVR initialization: " + ex.Message));
				((BaseUnityPlugin)this).Logger.LogError((object)("Stack trace: " + ex.StackTrace));
				try
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Attempting fallback initialization...");
					InitializeConfiguration();
					((BaseUnityPlugin)this).Logger.LogInfo((object)"H3TVR running in fallback mode with basic functionality");
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Critical error - H3TVR cannot initialize: " + ex2.Message));
				}
			}
		}

		private void InitializeConfiguration()
		{
			maxSlomo = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo", "MaxSlowmoScale", 0.1f, "Maximum slomo scale (0.01 = 1% speed, 0.1 = 10% speed)");
			slomoWaitTime = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo", "WaitTime", 2f, "Time to wait at max slomo before returning to normal speed");
			slomoScaleSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo", "ScaleDownSpeed", 1f, "Speed at which time slows down (higher = faster transition)");
			slomoReturnSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo", "ReturnSpeed", 0.33f, "Speed at which time returns to normal (higher = faster return)");
			slomoVRControllerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Slomo", "VRControllerEnabled", true, "Enable VR controller button to trigger slomo");
			slomoVRButton = ((BaseUnityPlugin)this).Config.Bind<string>("Slomo", "VRButton", "LeftX", "VR button to trigger slomo");
			slomoAffectsMovement = ((BaseUnityPlugin)this).Config.Bind<bool>("Slomo", "AffectsMovement", true, "Whether slomo affects player movement speed");
			slomoMovementScale = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo", "MovementScale", 0.3f, "Movement speed multiplier during slomo");
			slomoUseRampSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Slomo.Ramp", "UseRampSpeed", true, "Enable smooth ramp speed transitions for slomo (more cinematic)");
			slomoRampCurve = ((BaseUnityPlugin)this).Config.Bind<string>("Slomo.Ramp", "RampCurve", "EaseInOut", "Curve type for slomo ramp: Linear, EaseIn, EaseOut, EaseInOut, Smooth, Cinematic");
			slomoRampDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo.Ramp", "RampDuration", 0.5f, "Duration in seconds for slomo to ramp down to max slow speed");
			slomoReturnRampDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Slomo.Ramp", "ReturnRampDuration", 0.8f, "Duration in seconds for slomo to ramp back to normal speed");
			enableKillSlomo = ((BaseUnityPlugin)this).Config.Bind<bool>("Slomo", "EnableKillSlomo", true, "Enable slow motion effect on enemy kill.");
			useItemManagerForGunRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>("GunRandomization", "UseItemManager", true, "Use ItemManager for gun randomization (includes all H3VR and modded guns). If false, uses GunList/MagazineList config files.");
			gunList = ((BaseUnityPlugin)this).Config.Bind<string>("General", "GunList", "DefaultGunList", "List of guns");
			magazineList = ((BaseUnityPlugin)this).Config.Bind<string>("General", "MagazineList", "DefaultMagazineList", "List of magazines");
			InitializeSpawnConfigurations();
			InitializeKeyBindings();
		}

		private void InitializeSpawnConfigurations()
		{
			shurikenScale = ((BaseUnityPlugin)this).Config.Bind<float>("Shuriken", "Scale", 1f, "Scale multiplier for spawned shuriken");
			shurikenMinCount = ((BaseUnityPlugin)this).Config.Bind<int>("Shuriken", "MinCount", 1, "Minimum number of shuriken to spawn");
			shurikenMaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("Shuriken", "MaxCount", 3, "Maximum number of shuriken to spawn");
			pillowMinCount = ((BaseUnityPlugin)this).Config.Bind<int>("Pillow", "MinCount", 1, "Minimum number of pillows to spawn");
			pillowMaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("Pillow", "MaxCount", 3, "Maximum number of pillows to spawn");
			pillowGrenadeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Pillow", "GrenadeEnabled", true, "Enable pillow grenade effect");
			pillowGrenadeChance = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "GrenadeChance", 0.1f, "Chance for pillow to spawn grenade");
			pillowGrenadeArmedChance = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "GrenadeArmedChance", 0.3f, "Chance for pillow grenade to be armed");
			pillowZeroGravityEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Pillow", "ZeroGEnabled", true, "Enable pillow zero gravity effect");
			pillowZeroGravityChance = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "ZeroGChance", 0.15f, "Chance for pillow to trigger zero gravity");
			pillowZeroGravityDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "ZeroGDuration", 10f, "Duration of pillow zero gravity effect");
			pillowSlomoEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Pillow", "SlomoEnabled", true, "Enable pillow slow motion effect");
			pillowSlomoChance = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "SlomoChance", 0.2f, "Chance for pillow to trigger slow motion");
			pillowSlomoDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Pillow", "SlomoDuration", 8f, "Duration of pillow slow motion effect");
			dangerCloseMinCount = ((BaseUnityPlugin)this).Config.Bind<int>("DangerClose", "MinCount", 1, "Minimum danger close rounds");
			dangerCloseMaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("DangerClose", "MaxCount", 5, "Maximum danger close rounds");
			airStrikeGrenadeCount = ((BaseUnityPlugin)this).Config.Bind<int>("AirStrike", "GrenadeCount", 1, "Number of air strike grenades to spawn per redeem");
			airStrikePinPullChance = ((BaseUnityPlugin)this).Config.Bind<float>("AirStrike", "PinPullChance", 1f, "Chance (0.0 - 1.0) that each spawned air strike grenade has its pin pulled and is armed");
			enableInfiniteTokens = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold", "InfiniteTokens", false, "Enable infinite tokens in Take and Hold mode");
			disableEncryptionNodes = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold", "DisableEncryptionNodes", false, "Disable encryption nodes in Take and Hold mode for easier gameplay");
			disableAllEncryptions = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold.Encryption", "DisableAllEncryptions", false, "Master switch: Disable ALL encryption nodes (overrides specific settings)");
			disableEncryptionType1 = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold.Encryption", "DisableType1", false, "Disable Type 1 encryption nodes (pattern matching)");
			disableEncryptionType2 = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold.Encryption", "DisableType2", false, "Disable Type 2 encryption nodes (sequence)");
			disableEncryptionType3 = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold.Encryption", "DisableType3", false, "Disable Type 3 encryption nodes (timed)");
			autoCompleteEncryption = ((BaseUnityPlugin)this).Config.Bind<bool>("TakeAndHold.Encryption", "AutoComplete", false, "Automatically complete enabled encryption nodes after delay");
			encryptionCompletionDelay = ((BaseUnityPlugin)this).Config.Bind<float>("TakeAndHold.Encryption", "CompletionDelay", 2f, "Delay in seconds before auto-completing encryption (if AutoComplete enabled)");
		}

		private void InitializeKeyBindings()
		{
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, KeyValuePair<KeyCode, string>> dictionary = new Dictionary<string, KeyValuePair<KeyCode, string>>
			{
				{
					"SpawnWonderfulToy",
					new KeyValuePair<KeyCode, string>((KeyCode)257, "Spawn Wonderful Toy")
				},
				{
					"SpawnJeditToy",
					new KeyValuePair<KeyCode, string>((KeyCode)258, "Spawn Jedit Toy")
				},
				{
					"SpawnHydration",
					new KeyValuePair<KeyCode, string>((KeyCode)259, "Spawn Hydration")
				},
				{
					"SpawnPillow",
					new KeyValuePair<KeyCode, string>((KeyCode)260, "Spawn Pillow")
				},
				{
					"SpawnShuri",
					new KeyValuePair<KeyCode, string>((KeyCode)261, "Spawn Shuriken")
				},
				{
					"SpawnFlash",
					new KeyValuePair<KeyCode, string>((KeyCode)262, "Spawn Flash")
				},
				{
					"SpawnFlash2",
					new KeyValuePair<KeyCode, string>((KeyCode)263, "Spawn Flash2")
				},
				{
					"SpawnSkittySubGun",
					new KeyValuePair<KeyCode, string>((KeyCode)264, "Spawn Random Gun (Small)")
				},
				{
					"SpawnSkittyBigGun",
					new KeyValuePair<KeyCode, string>((KeyCode)265, "Spawn Random Gun (Large)")
				},
				{
					"SpawnNadeRain",
					new KeyValuePair<KeyCode, string>((KeyCode)267, "Spawn Grenade Rain")
				},
				{
					"DangerCloseBarrage",
					new KeyValuePair<KeyCode, string>((KeyCode)268, "Danger Close Barrage")
				},
				{
					"DestroyHeld",
					new KeyValuePair<KeyCode, string>((KeyCode)269, "Destroy Held Item")
				},
				{
					"DestroyQuickbelt",
					new KeyValuePair<KeyCode, string>((KeyCode)270, "Drop Quickbelt Items")
				},
				{
					"TriggerSlomo",
					new KeyValuePair<KeyCode, string>((KeyCode)102, "Trigger Slow Motion")
				},
				{
					"TriggerZeroG",
					new KeyValuePair<KeyCode, string>((KeyCode)103, "Trigger Zero Gravity")
				},
				{
					"ToggleFireMode",
					new KeyValuePair<KeyCode, string>((KeyCode)116, "Toggle Fire Mode")
				},
				{
					"BoostMalfunction",
					new KeyValuePair<KeyCode, string>((KeyCode)121, "Boost Malfunction")
				},
				{
					"ShowStats",
					new KeyValuePair<KeyCode, string>((KeyCode)9, "Show Stats")
				},
				{
					"SpawnAirStrike",
					new KeyValuePair<KeyCode, string>((KeyCode)291, "Spawn Air Strike Smoke Grenade")
				},
				{
					"SpawnTitanMachine",
					new KeyValuePair<KeyCode, string>((KeyCode)292, "Spawn Titan Machine (AI Enemy)")
				},
				{
					"SwapHeldGun",
					new KeyValuePair<KeyCode, string>((KeyCode)293, "Swap Held Gun for Random Gun")
				}
			};
			foreach (KeyValuePair<string, KeyValuePair<KeyCode, string>> item in dictionary)
			{
				keyBindings[item.Key] = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("KeyBindings", "KeyBindFor" + item.Key, item.Value.Key, item.Value.Value);
			}
		}

		private void InitializeOptionalDependencies()
		{
			try
			{
				OptionalDependencyManager.Initialize(((BaseUnityPlugin)this).Logger);
				MeatyceiverIntegrationManager.Initialize(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
				StovepipeIntegrationManager.Initialize(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
				if (OptionalDependencyManager.HasAnyDependencies())
				{
					int availableDependencyCount = OptionalDependencyManager.GetAvailableDependencyCount();
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"[H3TVRImproved] Enhanced functionality active with {availableDependencyCount} optional dependencies");
					if (OptionalDependencyManager.IsStovepipeAvailable)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[H3TVRImproved] Stovepipe integration active - realistic weapon malfunctions enabled");
					}
					if (OptionalDependencyManager.IsMeatyceiver2Available)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[H3TVRImproved] Meatyceiver 2 integration active - weapon transformations enabled");
					}
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[H3TVRImproved] Running in standard mode - no optional dependencies found");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[H3TVRImproved] Error initializing optional dependencies: " + ex.Message));
			}
		}

		private void InitializeAirdropManager()
		{
			airdropManager = ((Component)this).gameObject.AddComponent<AirdropManager>();
			airdropManager.Initialize(this, ((BaseUnityPlugin)this).Logger);
		}

		private void InitializeComponents()
		{
			try
			{
				slomoMovementController = ((Component)this).gameObject.AddComponent<SlomoMovementController>();
				slomoMovementController.Initialize(slomoMovementScale.Value, slomoAffectsMovement.Value, ((BaseUnityPlugin)this).Logger);
				inputHandler = ((Component)this).gameObject.AddComponent<InputHandler>();
				spawnManager = ((Component)this).gameObject.AddComponent<SpawnManager>();
				effectsManager = ((Component)this).gameObject.AddComponent<EffectsManager>();
				weaponManager = ((Component)this).gameObject.AddComponent<WeaponManager>();
				audioManager = ((Component)this).gameObject.AddComponent<AudioManager>();
				audioManager.Initialize(this, ((BaseUnityPlugin)this).Logger);
				inputHandler.Initialize(keyBindings, this);
				effectsManager.Initialize(this, slomoMovementController, ((BaseUnityPlugin)this).Logger);
				weaponManager.Initialize(this, ((BaseUnityPlugin)this).Logger, audioManager);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"All components initialized successfully");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Error initializing components: " + ex.Message));
				((BaseUnityPlugin)this).Logger.LogError((object)("Stack trace: " + ex.StackTrace));
			}
		}

		private void InitializeTwitchIntegration()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Twitch integration disabled");
		}

		public void Update()
		{
			HandleSlomoStateMachine();
			HandleZeroGravityStateMachine();
			HandleMalfunctionBoost();
			HandleInfiniteTokens();
			weaponManager?.UpdateScaleModifiers();
		}

		private void OnDestroy()
		{
		}

		private void HandleSlomoStateMachine()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				switch (slomoStatus)
				{
				case "Slowing":
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Slowing!");
					effectsManager.SlomoScaleDown();
					break;
				case "Wait":
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Waiting!");
					slomoStatus = "Paused";
					try
					{
						audioManager?.PlaySlomoSound("active");
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Audio error during slomo: " + ex.Message));
					}
					((MonoBehaviour)this).StartCoroutine(effectsManager.SlomoWait(delegate
					{
						slomoStatus = "Return";
					}));
					break;
				case "Return":
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Returning!");
					effectsManager.SlomoReturn();
					break;
				}
				if (Time.timeScale == 1f)
				{
					if (slomoStatus != "Off")
					{
						try
						{
							audioManager?.PlaySlomoSound("end");
						}
						catch (Exception ex2)
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)("Audio error ending slomo: " + ex2.Message));
						}
					}
					slomoStatus = "Off";
				}
				slomoMovementController?.UpdateMovementScale(Time.timeScale);
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Error in slomo state machine: " + ex3.Message));
				slomoStatus = "Off";
			}
		}

		private void HandleZeroGravityStateMachine()
		{
			if (zeroGStatus == "On")
			{
				((MonoBehaviour)this).StartCoroutine(effectsManager.ZeroGWait(delegate
				{
					zeroGStatus = "Falling";
					effectsManager.RealisticFall();
				}));
			}
			if (zeroGStatus == "Falling")
			{
				((MonoBehaviour)this).StartCoroutine(effectsManager.RealisticFallWait(delegate
				{
					effectsManager.ZeroGravityBumpUp();
					zeroGStatus = "Off";
				}));
			}
		}

		private void HandleMalfunctionBoost()
		{
			if (malfunctionBoostActive)
			{
				if (Time.time >= malfunctionBoostEndTime)
				{
					malfunctionBoostActive = false;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Meatyceiver malfunction boost ended.");
				}
				else
				{
					weaponManager.ApplyMalfunctionLogic();
				}
			}
		}

		private void HandleInfiniteTokens()
		{
			if (!enableInfiniteTokens.Value && !disableEncryptionNodes.Value && !disableAllEncryptions.Value)
			{
				return;
			}
			try
			{
				if ((Object)(object)GM.TNH_Manager != (Object)null && (Object)(object)GM.TNH_Manager.m_curHoldPoint != (Object)null)
				{
					if (enableInfiniteTokens.Value)
					{
						GM.TNH_Manager.m_numTokens = 999;
					}
					if (disableAllEncryptions.Value || disableEncryptionNodes.Value)
					{
						DisableEncryptionNodes();
					}
					else if (disableEncryptionType1.Value || disableEncryptionType2.Value || disableEncryptionType3.Value)
					{
						DisableSpecificEncryptionNodes();
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Error in HandleInfiniteTokens: " + ex.Message));
			}
		}

		private void DisableEncryptionNodes()
		{
			try
			{
				if ((Object)(object)GM.TNH_Manager == (Object)null || (Object)(object)GM.TNH_Manager.m_curHoldPoint == (Object)null)
				{
					return;
				}
				TNH_HoldPoint curHoldPoint = GM.TNH_Manager.m_curHoldPoint;
				if ((Object)(object)curHoldPoint.m_systemNode != (Object)null && !curHoldPoint.m_systemNode.m_hasActivated)
				{
					if (autoCompleteEncryption.Value)
					{
						((MonoBehaviour)this).StartCoroutine(AutoCompleteEncryptionDelayed(curHoldPoint.m_systemNode, encryptionCompletionDelay.Value));
						((BaseUnityPlugin)this).Logger.LogDebug((object)$"[TNH] Auto-completing all encryptions after {encryptionCompletionDelay.Value}s delay");
					}
					else
					{
						CompleteEncryptionNode(curHoldPoint.m_systemNode);
						((BaseUnityPlugin)this).Logger.LogDebug((object)"[TNH] Disabled all encryption nodes");
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Error disabling encryption nodes: " + ex.Message));
			}
		}

		private void DisableSpecificEncryptionNodes()
		{
			try
			{
				if ((Object)(object)GM.TNH_Manager == (Object)null || (Object)(object)GM.TNH_Manager.m_curHoldPoint == (Object)null)
				{
					return;
				}
				TNH_HoldPoint curHoldPoint = GM.TNH_Manager.m_curHoldPoint;
				if (!((Object)(object)curHoldPoint.m_systemNode != (Object)null) || curHoldPoint.m_systemNode.m_hasActivated)
				{
					return;
				}
				TNH_HoldPointSystemNode systemNode = curHoldPoint.m_systemNode;
				EncryptionType encryptionType = DetectEncryptionType(systemNode);
				bool flag = false;
				string text = "";
				switch (encryptionType)
				{
				case EncryptionType.Pattern:
					if (disableEncryptionType1.Value)
					{
						flag = true;
						text = "Pattern";
					}
					break;
				case EncryptionType.Sequence:
					if (disableEncryptionType2.Value)
					{
						flag = true;
						text = "Sequence";
					}
					break;
				case EncryptionType.Timed:
					if (disableEncryptionType3.Value)
					{
						flag = true;
						text = "Timed";
					}
					break;
				case EncryptionType.Unknown:
					if (disableEncryptionType1.Value || disableEncryptionType2.Value || disableEncryptionType3.Value)
					{
						flag = true;
						text = "Unknown";
					}
					break;
				}
				if (flag)
				{
					if (autoCompleteEncryption.Value)
					{
						((MonoBehaviour)this).StartCoroutine(AutoCompleteEncryptionDelayed(systemNode, encryptionCompletionDelay.Value));
						((BaseUnityPlugin)this).Logger.LogDebug((object)$"[TNH] Auto-completing {text} encryption after {encryptionCompletionDelay.Value}s delay");
					}
					else
					{
						CompleteEncryptionNode(systemNode);
						((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Disabled " + text + " encryption"));
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Error disabling specific encryption: " + ex.Message));
			}
		}

		private EncryptionType DetectEncryptionType(TNH_HoldPointSystemNode encryptionNode)
		{
			try
			{
				if ((Object)(object)encryptionNode == (Object)null)
				{
					return EncryptionType.Unknown;
				}
				return EncryptionType.Unknown;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Error detecting encryption type: " + ex.Message));
				return EncryptionType.Unknown;
			}
		}

		private void CompleteEncryptionNode(TNH_HoldPointSystemNode encryptionNode)
		{
			try
			{
				if (!((Object)(object)encryptionNode == (Object)null) && (Object)(object)((Component)encryptionNode).gameObject != (Object)null)
				{
					((Component)encryptionNode).gameObject.SetActive(false);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Error completing encryption node: " + ex.Message));
			}
		}

		private IEnumerator AutoCompleteEncryptionDelayed(TNH_HoldPointSystemNode encryptionNode, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			try
			{
				if ((Object)(object)encryptionNode != (Object)null && (Object)(object)((Component)encryptionNode).gameObject != (Object)null && ((Component)encryptionNode).gameObject.activeSelf)
				{
					CompleteEncryptionNode(encryptionNode);
					((BaseUnityPlugin)this).Logger.LogDebug((object)$"[TNH] Auto-completed encryption after {delay}s delay");
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[TNH] Error auto-completing encryption: " + ex2.Message));
			}
		}

		public void TriggerSlomo()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			slomoStatus = "Slowing";
			slomoRampStartTime = Time.unscaledTime;
			slomoRampStartValue = Time.timeScale;
			isRamping = true;
			audioManager?.PlaySlomoSound();
		}

		public void TriggerZeroGravity()
		{
			effectsManager.ZeroGravityBumpDown();
		}

		public void ActivateMalfunctionBoost()
		{
			weaponManager.ActivateMalfunctionBoost(ref malfunctionBoostActive, ref malfunctionBoostEndTime);
		}

		public SpawnManager GetSpawnManager()
		{
			return spawnManager;
		}

		public WeaponManager GetWeaponManager()
		{
			return weaponManager;
		}

		public EffectsManager GetEffectsManager()
		{
			return effectsManager;
		}

		public AudioManager GetAudioManager()
		{
			return audioManager;
		}

		public AirdropManager GetAirdropManager()
		{
			return airdropManager;
		}

		public void GetShurikenConfig(out int min, out int max)
		{
			min = shurikenMinCount.Value;
			max = shurikenMaxCount.Value;
		}

		public float GetShurikenScale()
		{
			return shurikenScale.Value;
		}

		public void GetPillowConfig(out int min, out int max)
		{
			min = pillowMinCount.Value;
			max = pillowMaxCount.Value;
		}

		public void GetDangerCloseConfig(out int min, out int max)
		{
			min = dangerCloseMinCount.Value;
			max = dangerCloseMaxCount.Value;
		}

		public void GetAirStrikeConfig(out int count, out float pinPullChance)
		{
			count = ((airStrikeGrenadeCount == null) ? 1 : Mathf.Max(1, airStrikeGrenadeCount.Value));
			pinPullChance = ((airStrikePinPullChance != null) ? Mathf.Clamp01(airStrikePinPullChance.Value) : 1f);
		}

		public void GetPillowGrenadeConfig(out bool enabled, out float chance, out float armedChance)
		{
			enabled = pillowGrenadeEnabled.Value;
			chance = pillowGrenadeChance.Value;
			armedChance = pillowGrenadeArmedChance.Value;
		}

		public void GetPillowZeroGravityConfig(out bool enabled, out float chance, out float duration)
		{
			enabled = pillowZeroGravityEnabled.Value;
			chance = pillowZeroGravityChance.Value;
			duration = pillowZeroGravityDuration.Value;
		}

		public void GetPillowSlomoConfig(out bool enabled, out float chance, out float duration)
		{
			enabled = pillowSlomoEnabled.Value;
			chance = pillowSlomoChance.Value;
			duration = pillowSlomoDuration.Value;
		}

		public bool UseItemManagerForGuns()
		{
			return useItemManagerForGunRandomization.Value;
		}

		public bool IsKillSlomoEnabled()
		{
			return enableKillSlomo.Value;
		}

		public void GetGunLists(out string gunListValue, out string magListValue)
		{
			gunListValue = gunList.Value;
			magListValue = magazineList.Value;
		}

		public void GetSlomoConfig(out float maxSlomoValue, out float waitTime, out float scaleSpeed, out float returnSpeed)
		{
			maxSlomoValue = maxSlomo.Value;
			waitTime = slomoWaitTime.Value;
			scaleSpeed = slomoScaleSpeed.Value;
			returnSpeed = slomoReturnSpeed.Value;
		}

		public void GetSlomoRampConfig(out bool useRamp, out string curve, out float rampDuration, out float returnDuration)
		{
			useRamp = slomoUseRampSpeed.Value;
			curve = slomoRampCurve.Value;
			rampDuration = slomoRampDuration.Value;
			returnDuration = slomoReturnRampDuration.Value;
		}

		public void GetSlomoAudioConfig(out bool affectsAudio, out float pitchScale, out bool preservePitch)
		{
			affectsAudio = true;
			pitchScale = 1f;
			preservePitch = false;
		}

		public void GetSlomoAudioConfigComplete(out bool affectsAudio, out float pitchScale, out bool preservePitch, out bool affectsSpeed, out float speedScale, out string mode)
		{
			affectsAudio = true;
			pitchScale = 1f;
			preservePitch = false;
			affectsSpeed = false;
			speedScale = 1f;
			mode = "Both";
		}

		public void GetSlomoMovementConfig(out bool affectsMovement, out float movementScale)
		{
			affectsMovement = slomoAffectsMovement.Value;
			movementScale = slomoMovementScale.Value;
		}

		public void UpdateSlomoMovementSettings()
		{
			slomoMovementController?.UpdateSettings(slomoMovementScale.Value, slomoAffectsMovement.Value);
		}

		public void SetSlomoStatus(string status)
		{
			slomoStatus = status;
		}

		public bool IsInfiniteTokensEnabled()
		{
			return enableInfiniteTokens != null && enableInfiniteTokens.Value;
		}

		public bool IsEncryptionDisabled()
		{
			return disableEncryptionNodes != null && disableEncryptionNodes.Value;
		}

		public void SetInfiniteTokens(bool enabled)
		{
			if (enableInfiniteTokens != null)
			{
				enableInfiniteTokens.Value = enabled;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Infinite tokens " + (enabled ? "enabled" : "disabled")));
			}
		}

		public void SetEncryptionNodes(bool disabled)
		{
			if (disableEncryptionNodes != null)
			{
				disableEncryptionNodes.Value = disabled;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Encryption nodes " + (disabled ? "disabled" : "enabled")));
			}
		}

		public void GetSlomoVRConfig(out bool vrEnabled, out string vrButton)
		{
			vrEnabled = slomoVRControllerEnabled.Value;
			vrButton = slomoVRButton.Value;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static void FixPitch(AudioSource __instance, ref float value)
		{
			H3TVRImproved h3TVRImproved = Object.FindObjectOfType<H3TVRImproved>();
			if ((Object)(object)h3TVRImproved == (Object)null)
			{
				return;
			}
			if (Time.timeScale >= 0.99f && Time.timeScale <= 1.01f)
			{
				if (originalAudioSpeeds.ContainsKey(__instance))
				{
					originalAudioSpeeds.Remove(__instance);
				}
				return;
			}
			h3TVRImproved.GetSlomoAudioConfigComplete(out bool affectsAudio, out float pitchScale, out bool preservePitch, out bool affectsSpeed, out float speedScale, out string mode);
			if (!affectsAudio)
			{
				return;
			}
			if (!originalAudioSpeeds.ContainsKey(__instance))
			{
				originalAudioSpeeds[__instance] = 1f;
			}
			switch (mode.ToLower())
			{
			case "pitchonly":
				ApplyPitchAdjustment(ref value, preservePitch, pitchScale);
				break;
			case "speedonly":
				ApplySpeedAdjustment(__instance, speedScale);
				value = 1f;
				break;
			case "both":
				ApplyPitchAdjustment(ref value, preservePitch, pitchScale);
				if (affectsSpeed)
				{
					ApplySpeedAdjustment(__instance, speedScale);
				}
				break;
			case "independent":
				ApplyPitchAdjustment(ref value, preservePitch, pitchScale);
				if (affectsSpeed)
				{
					ApplySpeedAdjustment(__instance, speedScale);
				}
				break;
			default:
				ApplyPitchAdjustment(ref value, preservePitch, pitchScale);
				if (affectsSpeed)
				{
					ApplySpeedAdjustment(__instance, speedScale);
				}
				break;
			}
			value = Mathf.Clamp(value, 0.1f, 3f);
		}

		private static void ApplyPitchAdjustment(ref float pitch, bool preservePitch, float pitchScale)
		{
			if (preservePitch)
			{
				pitch *= 1f / Time.timeScale;
				return;
			}
			float num = pitch * (Time.timeScale * pitchScale);
			pitch = Mathf.Clamp(num, 0.1f, 3f);
		}

		private static void ApplySpeedAdjustment(AudioSource source, float speedScale)
		{
			if ((Object)(object)source == (Object)null || (Object)(object)source.clip == (Object)null)
			{
				return;
			}
			try
			{
				float num = Time.timeScale * speedScale;
				num = Mathf.Clamp(num, 0.1f, 3f);
				if (source.isPlaying && num < 0.95f)
				{
					float num2 = source.time / source.clip.length;
					int num3 = Mathf.RoundToInt((float)source.timeSamples * num);
					if (Mathf.Abs(num3 - source.timeSamples) > 100)
					{
						source.timeSamples = Mathf.Clamp(num3, 0, source.clip.samples - 1);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error applying speed adjustment: " + ex.Message));
			}
		}
	}
	internal static class PluginInfo
	{
		internal const string NAME = "H3TVR";

		internal const string GUID = "com.MrBeam.h3tvr";

		internal const string VERSION = "1.1.4";
	}
	public static class MeatyceiverIntegrationManager
	{
		public enum WeaponQuality
		{
			Common,
			Uncommon,
			Rare,
			Epic,
			Legendary,
			Artifact
		}

		private static ManualLogSource logger;

		private static bool initialized = false;

		private static Type meatyceiverType;

		private static object meatyceiverInstance;

		private static MethodInfo transformMethod;

		private static MethodInfo checkCompatibilityMethod;

		private static MethodInfo isTransformedMethod;

		private static MethodInfo getQualityMethod;

		private static MethodInfo setQualityMethod;

		private static PropertyInfo transformChanceProperty;

		private static FieldInfo enabledField;

		private static ConfigFile config;

		private static Dictionary<string, ConfigEntry<float>> chanceConfigs;

		private static Dictionary<string, ConfigEntry<bool>> featureConfigs;

		private static Dictionary<string, ConfigEntry<float>> multiplierConfigs;

		private static Dictionary<string, ConfigEntry<int>> intConfigs;

		private static readonly Dictionary<string, bool> transformationCache = new Dictionary<string, bool>();

		private static readonly Dictionary<string, DateTime> transformationTimes = new Dictionary<string, DateTime>();

		private static readonly Dictionary<string, DateTime> transformationCooldowns = new Dictionary<string, DateTime>();

		private static readonly Dictionary<string, WeaponQuality> weaponQualities = new Dictionary<string, WeaponQuality>();

		private static DateTime lastCacheClear = DateTime.Now;

		private const string MEATYCEIVER2_GUID = "Potatoes.Meatyceiver_2";

		private const string MEATYCEIVER_LEGACY_GUID = "potatoes1286.meatyceiver";

		private const string MEATYCEIVER_ALPHA_GUID = "potatoes.meatyceiver.alpha";

		public static bool IsMeatyceiver2Available { get; private set; } = false;

		public static string DetectedVersion { get; private set; } = "Unknown";

		public static string DetectedApiVersion { get; private set; } = "Unknown";

		public static int TotalTransformationAttempts { get; private set; } = 0;

		public static int SuccessfulTransformations { get; private set; } = 0;

		public static int CachedResults { get; private set; } = 0;

		public static int CooldownBlocked { get; private set; } = 0;

		public static int QualityPreserved { get; private set; } = 0;

		public static Dictionary<string, int> TransformationsByContext { get; private set; } = new Dictionary<string, int>();

		public static Dictionary<string, int> TransformationsByWeaponType { get; private set; } = new Dictionary<string, int>();

		public static void Initialize(ManualLogSource logSource, ConfigFile configFile)
		{
			if (!initialized)
			{
				logger = logSource;
				config = configFile;
				logger.LogInfo((object)"[MeatyceiverIntegration] Initializing Meatyceiver 2 integration...");
				InitializeConfiguration();
				DetectMeatyceiver2();
				if (IsMeatyceiver2Available)
				{
					CacheMeatyceiverMethods();
					InitializeCompatibilityLayer();
					logger.LogInfo((object)("[MeatyceiverIntegration] Successfully initialized with Meatyceiver 2 " + DetectedVersion + " (API: " + DetectedApiVersion + ")"));
				}
				else
				{
					logger.LogInfo((object)"[MeatyceiverIntegration] Meatyceiver 2 not detected - integration disabled");
				}
				initialized = true;
			}
		}

		private static void InitializeConfiguration()
		{
			chanceConfigs = new Dictionary<string, ConfigEntry<float>>();
			featureConfigs = new Dictionary<string, ConfigEntry<bool>>();
			multiplierConfigs = new Dictionary<string, ConfigEntry<float>>();
			intConfigs = new Dictionary<string, ConfigEntry<int>>();
			chanceConfigs["Normal"] = config.Bind<float>("Meatyceiver 2", "ChanceNormal", 0.02f, "Normal transformation chance");
			chanceConfigs["Elite"] = config.Bind<float>("Meatyceiver 2", "ChanceElite", 0.01f, "Elite sosig transformation chance");
			chanceConfigs["Chaos"] = config.Bind<float>("Meatyceiver 2", "ChanceChaos", 0.15f, "Chaos mode transformation chance");
			chanceConfigs["Player"] = config.Bind<float>("Meatyceiver 2", "ChancePlayer", 0.05f, "Player weapon transformation chance");
			chanceConfigs["SosigWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceSosigWeapon", 0.03f, "Sosig weapon transformation chance");
			chanceConfigs["EnemyWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceEnemyWeapon", 0.04f, "Enemy weapon transformation chance");
			chanceConfigs["AllyWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceAllyWeapon", 0.02f, "Ally weapon transformation chance");
			chanceConfigs["BossWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceBossWeapon", 0.001f, "Boss weapon transformation chance");
			chanceConfigs["RareWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceRareWeapon", 0.005f, "Rare weapon transformation chance");
			chanceConfigs["LegendaryWeapon"] = config.Bind<float>("Meatyceiver 2", "ChanceLegendaryWeapon", 0.001f, "Legendary weapon transformation chance");
			multiplierConfigs["Pistol"] = config.Bind<float>("Meatyceiver 2", "PistolMultiplier", 1.2f, "Pistol transformation multiplier");
			multiplierConfigs["Rifle"] = config.Bind<float>("Meatyceiver 2", "RifleMultiplier", 1f, "Rifle transformation multiplier");
			multiplierConfigs["Shotgun"] = config.Bind<float>("Meatyceiver 2", "ShotgunMultiplier", 0.8f, "Shotgun transformation multiplier");
			multiplierConfigs["SMG"] = config.Bind<float>("Meatyceiver 2", "SMGMultiplier", 1.5f, "SMG transformation multiplier");
			multiplierConfigs["Sniper"] = config.Bind<float>("Meatyceiver 2", "SniperMultiplier", 0.5f, "Sniper transformation multiplier");
			multiplierConfigs["LMG"] = config.Bind<float>("Meatyceiver 2", "LMGMultiplier", 0.7f, "LMG transformation multiplier");
			multiplierConfigs["AssaultRifle"] = config.Bind<float>("Meatyceiver 2", "AssaultRifleMultiplier", 0.9f, "Assault rifle transformation multiplier");
			multiplierConfigs["CommonQuality"] = config.Bind<float>("Meatyceiver 2", "CommonQualityMultiplier", 1f, "Common quality transformation multiplier");
			multiplierConfigs["UncommonQuality"] = config.Bind<float>("Meatyceiver 2", "UncommonQualityMultiplier", 0.8f, "Uncommon quality transformation multiplier");
			multiplierConfigs["RareQuality"] = config.Bind<float>("Meatyceiver 2", "RareQualityMultiplier", 0.6f, "Rare quality transformation multiplier");
			multiplierConfigs["EpicQuality"] = config.Bind<float>("Meatyceiver 2", "EpicQualityMultiplier", 0.4f, "Epic quality transformation multiplier");
			multiplierConfigs["LegendaryQuality"] = config.Bind<float>("Meatyceiver 2", "LegendaryQualityMultiplier", 0.2f, "Legendary quality transformation multiplier");
			multiplierConfigs["ArtifactQuality"] = config.Bind<float>("Meatyceiver 2", "ArtifactQualityMultiplier", 0.1f, "Artifact quality transformation multiplier");
			featureConfigs["Enabled"] = config.Bind<bool>("Meatyceiver 2", "Enabled", true, "Enable Meatyceiver 2 integration");
			featureConfigs["ForceTransformOnChaos"] = config.Bind<bool>("Meatyceiver 2", "ForceTransformOnChaos", false, "Force transformation in chaos mode");
			featureConfigs["AllowMultipleTransforms"] = config.Bind<bool>("Meatyceiver 2", "AllowMultipleTransforms", false, "Allow multiple transformations");
			featureConfigs["PreserveAmmo"] = config.Bind<bool>("Meatyceiver 2", "PreserveAmmo", true, "Preserve ammo during transformation");
			featureConfigs["PreserveAttachments"] = config.Bind<bool>("Meatyceiver 2", "PreserveAttachments", true, "Preserve attachments during transformation");
			featureConfigs["PreserveQuality"] = config.Bind<bool>("Meatyceiver 2", "PreserveQuality", true, "Preserve weapon quality during transformation");
			featureConfigs["PlayTransformSound"] = config.Bind<bool>("Meatyceiver 2", "PlayTransformSound", true, "Play transformation sound effects");
			featureConfigs["ShowTransformParticles"] = config.Bind<bool>("Meatyceiver 2", "ShowTransformParticles", true, "Show transformation particle effects");
			featureConfigs["EnableCaching"] = config.Bind<bool>("Meatyceiver 2", "EnableCaching", true, "Enable transformation result caching");
			featureConfigs["EnableCooldowns"] = config.Bind<bool>("Meatyceiver 2", "EnableCooldowns", true, "Enable transformation cooldowns");
			featureConfigs["RespectOriginalChances"] = config.Bind<bool>("Meatyceiver 2", "RespectOriginalChances", true, "Respect Meatyceiver 2's original chances");
			featureConfigs["UseContextualLogic"] = config.Bind<bool>("Meatyceiver 2", "UseContextualLogic", true, "Use H3TVR contextual logic");
			featureConfigs["UseQualityBasedChances"] = config.Bind<bool>("Meatyceiver 2", "UseQualityBasedChances", true, "Use weapon quality to modify transformation chances");
			featureConfigs["EnableBatchTransformation"] = config.Bind<bool>("Meatyceiver 2", "EnableBatchTransformation", true, "Enable batch transformation support");
			featureConfigs["DebugMode"] = config.Bind<bool>("Meatyceiver 2", "DebugMode", false, "Enable debug mode");
			featureConfigs["VerboseLogging"] = config.Bind<bool>("Meatyceiver 2", "VerboseLogging", false, "Enable verbose logging");
			intConfigs["CooldownSeconds"] = config.Bind<int>("Meatyceiver 2", "CooldownSeconds", 30, "Cooldown between transformations (seconds)");
			intConfigs["CacheLifetimeMinutes"] = config.Bind<int>("Meatyceiver 2", "CacheLifetimeMinutes", 10, "Cache entry lifetime in minutes");
			intConfigs["MaxCacheSize"] = config.Bind<int>("Meatyceiver 2", "MaxCacheSize", 1000, "Maximum number of cached entries");
			intConfigs["BatchSize"] = config.Bind<int>("Meatyceiver 2", "BatchSize", 10, "Maximum weapons to transform in a single batch");
		}

		private static void DetectMeatyceiver2()
		{
			try
			{
				Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
				if (pluginInfos.ContainsKey("Potatoes.Meatyceiver_2"))
				{
					IsMeatyceiver2Available = true;
					DetectedVersion = pluginInfos["Potatoes.Meatyceiver_2"].Metadata.Version.ToString();
					logger.LogInfo((object)("[MeatyceiverIntegration] Meatyceiver 2 detected via BepInEx: v" + DetectedVersion));
				}
				else if (pluginInfos.ContainsKey("potatoes1286.meatyceiver"))
				{
					IsMeatyceiver2Available = true;
					DetectedVersion = pluginInfos["potatoes1286.meatyceiver"].Metadata.Version.ToString();
					logger.LogInfo((object)("[MeatyceiverIntegration] Meatyceiver detected via legacy GUID: v" + DetectedVersion));
				}
				else if (pluginInfos.ContainsKey("potatoes.meatyceiver.alpha"))
				{
					IsMeatyceiver2Available = true;
					DetectedVersion = pluginInfos["potatoes.meatyceiver.alpha"].Metadata.Version.ToString();
					logger.LogInfo((object)("[MeatyceiverIntegration] Meatyceiver Alpha detected via GUID: v" + DetectedVersion));
				}
				else
				{
					DetectViaReflection();
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("[MeatyceiverIntegration] Error during Meatyceiver 2 detection: " + ex.Message));
				IsMeatyceiver2Available = false;
			}
		}

		private static void DetectViaReflection()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				try
				{
					Type[] types = assembly.GetTypes();
					Type[] array2 = types;
					foreach (Type type in array2)
					{
						if (IsMeatyceiverType(type))
						{
							meatyceiverType = type;
							IsMeatyceiver2Available = true;
							DetectedVersion = assembly.GetName().Version?.ToString() ?? "Unknown";
							logger.LogInfo((object)("[MeatyceiverIntegration] Meatyceiver detected via reflection: " + type.FullName));
							return;
						}
					}
				}
				catch (Exception ex)
				{
					logger.LogDebug((object)("[MeatyceiverIntegration] Could not scan assembly " + assembly.FullName + ": " + ex.Message));
				}
			}
		}

		private static bool IsMeatyceiverType(Type type)
		{
			if ((object)type == null)
			{
				return false;
			}
			string text = type.Name.ToLower();
			string text2 = type.Namespace?.ToLower() ?? "";
			return text.Contains("meatyceiver") || text.Contains("meatyreceiver") || text.Contains("meattransform") || text2.Contains("meatyceiver") || text2.Contains("potatoes") || (text.Contains("meat") && (text.Contains("weapon") || text.Contains("transform")));
		}

		private static void CacheMeatyceiverMethods()
		{
			if ((object)meatyceiverType == null)
			{
				return;
			}
			try
			{
				FieldInfo field = meatyceiverType.GetField("Instance", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					field = meatyceiverType.GetField("instance", BindingFlags.Static | BindingFlags.Public);
				}
				if ((object)field != null)
				{
					meatyceiverInstance = field.GetValue(null);
					logger.LogDebug((object)"[MeatyceiverIntegration] Found Meatyceiver instance");
				}
				MethodInfo[] methods = meatyceiverType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo in array)
				{
					string text = methodInfo.Name.ToLower();
					if ((text.Contains("transform") || text.Contains("meat")) && !text.Contains("check") && !text.Contains("is"))
					{
						transformMethod = methodInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached transform method: " + methodInfo.Name));
					}
					else if (text.Contains("check") || text.Contains("compatible") || text.Contains("can"))
					{
						checkCompatibilityMethod = methodInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached compatibility method: " + methodInfo.Name));
					}
					else if (text.Contains("is") && (text.Contains("transform") || text.Contains("meat")))
					{
						isTransformedMethod = methodInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached is-transformed method: " + methodInfo.Name));
					}
					else if (text.Contains("quality") && text.Contains("get"))
					{
						getQualityMethod = methodInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached get quality method: " + methodInfo.Name));
					}
					else if (text.Contains("quality") && text.Contains("set"))
					{
						setQualityMethod = methodInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached set quality method: " + methodInfo.Name));
					}
				}
				PropertyInfo[] properties = meatyceiverType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
				PropertyInfo[] array2 = properties;
				foreach (PropertyInfo propertyInfo in array2)
				{
					string text2 = propertyInfo.Name.ToLower();
					if (text2.Contains("chance") || text2.Contains("probability"))
					{
						transformChanceProperty = propertyInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached chance property: " + propertyInfo.Name));
					}
				}
				FieldInfo[] fields = meatyceiverType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
				FieldInfo[] array3 = fields;
				foreach (FieldInfo fieldInfo in array3)
				{
					string text3 = fieldInfo.Name.ToLower();
					if (text3.Contains("enabled") || text3.Contains("active"))
					{
						enabledField = fieldInfo;
						logger.LogDebug((object)("[MeatyceiverIntegration] Cached enabled field: " + fieldInfo.Name));
					}
				}
			}
			catch (Exception ex)
			{
				logger.LogWarning((object)("[MeatyceiverIntegration] Error caching Meatyceiver methods: " + ex.Message));
			}
		}

		private static void InitializeCompatibilityLayer()
		{
			try
			{
				if ((object)getQualityMethod != null && (object)setQualityMethod != null)
				{
					DetectedApiVersion = "2.0+";
					logger.LogDebug((object)"[MeatyceiverIntegration] Detected advanced API with quality support");
				}
				else if ((object)transformMethod != null)
				{
					DetectedApiVersion = "1.5+";
					logger.LogDebug((object)"[MeatyceiverIntegration] Detected basic transformation API");
				}
				else
				{
					DetectedApiVersion = "1.0";
					logger.LogWarning((object)"[MeatyceiverIntegration] Limited API detected - some features may not work");
				}
			}
			catch (Exception ex)
			{
				logger.LogWarning((object)("[MeatyceiverIntegration] Error initializing compatibility layer: " + ex.Message));
				DetectedApiVersion = "Unknown";
			}
		}

		public static bool TryTransformWeapon(FVRFireArm firearm, string context = "Normal", float customChance = -1f, bool forceTransform = false)
		{
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			if (!IsIntegrationEnabled() || (Object)(object)firearm == (Object)null)
			{
				return false;
			}
			TotalTransformationAttempts++;
			try
			{
				string weaponKey = GetWeaponKey(firearm);
				if (featureConfigs["EnableCooldowns"].Value && IsOnCooldown(weaponKey) && !forceTransform)
				{
					CooldownBlocked++;
					if (featureConfigs["VerboseLogging"].Value)
					{
						logger.LogDebug((object)("[MeatyceiverIntegration] Transformation blocked by cooldown for " + weaponKey));
					}
					return false;
				}
				if (featureConfigs["EnableCaching"].Value && transformationCache.ContainsKey(weaponKey))
				{
					CachedResults++;
					bool flag = transformationCache[weaponKey];
					if (featureConfigs["VerboseLogging"].Value)
					{
						logger.LogDebug((object)$"[MeatyceiverIntegration] Using cached result for {weaponKey}: {flag}");
					}
					return flag;
				}
				if (!CanWeaponBeTransformed(firearm) && !forceTransform)
				{
					CacheResult(weaponKey, result: false);
					return false;
				}
				float num = ((customChance >= 0f) ? customChance : CalculateTransformationChance(firearm, context));
				if (!forceTransform && Random.value > num)
				{
					if (featureConfigs["VerboseLogging"].Value)
					{
						logger.LogDebug((object)$"[MeatyceiverIntegration] Transformation chance failed: {num:P2}");
					}
					CacheResult(weaponKey, result: false);
					return false;
				}
				bool flag2 = PerformTransformation(firearm, context);
				if (flag2)
				{
					SuccessfulTransformations++;
					UpdateTransformationStatistics(context, firearm);
					if (featureConfigs["EnableCooldowns"].Value)
					{
						SetCooldown(weaponKey);
					}
					logger.LogInfo((object)("[MeatyceiverIntegration] Successfully transformed " + ((Object)firearm).name + " (context: " + context + ")"));
					if (featureConfigs["PlayTransformSound"].Value)
					{
						PlayTransformationSound(((Component)firearm).transform.position);
					}
					if (featureConfigs["ShowTransformParticles"].Value)
					{
						ShowTransformationParticles(((Component)firearm).transform.position);
					}
				}
				CacheResult(weaponKey, flag2);
				return flag2;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("[MeatyceiverIntegration] Error during weapon transformation: " + ex.Message));
				return false;
			}
		}

		public static Dictionary<FVRFireArm, bool> TryTransformWeaponsBatch(List<FVRFireArm> firearms, string context = "Normal", float customChance = -1f, bool forceTransform = false)
		{
			Dictionary<FVRFireArm, bool> dictionary = new Dictionary<FVRFireArm, bool>();
			if (!IsIntegrationEnabled() || !featureConfigs["EnableBatchTransformation"].Value)
			{
				foreach (FVRFireArm firearm in firearms)
				{
					dictionary[firearm] = false;
				}
				return dictionary;
			}
			int batchSize = intConfigs["BatchSize"].Value;
			List<List<FVRFireArm>> list = (from x in firearms.Select((FVRFireArm x, int i) => new
				{
					Index = i,
					Value = x
				})
				group x by x.Index / batchSize into x
				select x.Select(v => v.Value).ToList()).ToList();
			foreach (List<FVRFireArm> item in list)
			{
				foreach (FVRFireArm item2 in item)
				{
					dictionary[item2] = TryTransformWeapon(item2, context, customChance, forceTransform);
				}
			}
			logger.LogDebug((object)$"[MeatyceiverIntegration] Batch transformation completed: {dictionary.Count((KeyValuePair<FVRFireArm, bool> r) => r.Value)}/{dictionary.Count} successful");
			return dictionary;
		}

		public static bool CanWeaponBeTransformed(FVRFireArm firearm)
		{
			if (!IsIntegrationEnabled() || (Object)(object)firearm == (Object)null)
			{
				return false;
			}
			try
			{
				if ((object)checkCompatibilityMethod != null)
				{
					return (bool)checkCompatibilityMethod.Invoke(meatyceiverInstance, new object[1] { firearm });
				}
				if (IsWeaponAlreadyTransformed(firearm))
				{
					return featureConfigs["AllowMultipleTransforms"].Value;
				}
				string text = ((Object)firearm).name.ToLower();
				return !text.Contains("meat") && !text.Contains("flesh") && !text.Contains("organic") && !text.Contains("bio");
			}
			catch (Exception ex)
			{
				logger.LogError((object)("[MeatyceiverIntegration] Error checking weapon compatibility: " + ex.Message));
				return false;
			}
		}

		public static bool IsWeaponAlreadyTransformed(FVRFireArm firearm)
		{
			if ((Object)(object)firearm == (Object)null)
			{
				return false;
			}
			try
			{
				if ((object)isTransformedMethod != null)
				{
					return (bool)isTransformedMethod.Invoke(meatyceiverInstance, new object[1] { firearm });
				}
				string text = ((Object)firearm).name.ToLower();
				return text.Contains("meat") || text.Contains("flesh") || text.Contains("organic");
			}
			catch (Exception ex)
			{
				logger.LogDebug((object)("[MeatyceiverIntegration] Error checking transformation status: " + ex.Message));
				return false;
			}
		}

		public static WeaponQuality GetWeaponQuality(FVRFireArm firearm)
		{
			if ((Object)(object)firearm == (Object)null)
			{
				return WeaponQuality.Common;
			}
			try
			{
				string weaponKey = GetWeaponKey(firearm);
				if (weaponQualities.ContainsKey(weaponKey))
				{
					return weaponQualities[weaponKey];
				}
				if ((object)getQualityMethod != null && getQualityMethod.Invoke(meatyceiverInstance, new object[1] { firearm }) is int val)
				{
					WeaponQuality weaponQuality = (WeaponQuality)Math.Min(val, 5);
					weaponQualities[weaponKey] = weaponQuality;
					return weaponQuality;
				}
				WeaponQuality weaponQuality2 = DetectWeaponQualityFallback(firearm);
				weaponQualities[weaponKey] = weaponQuality2;
				return weaponQuality2;
			}
			catch (Exception ex)
			{
				logger.LogDebug((object)("[MeatyceiverIntegration] Error getting weapon quality: " + ex.Message));
				return WeaponQuality.Common;
			}
		}

		public static string GetTransformationStats()
		{
			float num = ((TotalTransformationAttempts > 0) ? ((float)SuccessfulTransformations / (float)TotalTransformationAttempts * 100f) : 0f);
			string text = string.Join(", ", TransformationsByContext.Select<KeyValuePair<string, int>, string>((KeyValuePair<string, int> kvp) => $"{kvp.Key}: {kvp.Value}").ToArray());
			string text2 = string.Join(", ", TransformationsByWeaponType.Select<KeyValuePair<string, int>, string>((KeyValuePair<string, int> kvp) => $"{kvp.Key}: {kvp.Value}").ToArray());
			return "Meatyceiver 2 Integration Stats:\n• Status: " + (IsMeatyceiver2Available ? "✓ Active" : "✗ Not Available") + "\n• Version: " + DetectedVersion + " (API: " + DetectedApiVersion + ")\n" + $"• Attempts: {TotalTransformationAttempts}\n" + $"• Successes: {SuccessfulTransformations}\n" + $"• Success Rate: {num:F1}%\n" + $"• Cached Results: {CachedResults}\n" + $"• Cooldown Blocked: {CooldownBlocked}\n" + $"• Quality Preserved: {QualityPreserved}\n" + $"• Cache Size: {transformationCache.Count}\n" + "• By Context: " + text + "\n• By Weapon Type: " + text2;
		}

		public static void ClearCache()
		{
			transformationCache.Clear();
			transformationTimes.Clear();
			transformationCooldowns.Clear();
			weaponQualities.Clear();
			CachedResults = 0;
			logger.LogDebug((object)"[MeatyceiverIntegration] Cache cleared");
		}

		public static bool IsIntegrationEnabled()
		{
			return IsMeatyceiver2Available && featureConfigs["Enabled"].Value;
		}

		public static string GetCompatibilityInfo()
		{
			if (!IsMeatyceiver2Available)
			{
				return "Meatyceiver 2 not detected";
			}
			List<string> list = new List<string>();
			if ((object)transformMethod != null)
			{
				list.Add("Basic Transformation");
			}
			if ((object)checkCompatibilityMethod != null)
			{
				list.Add("Compatibility Checking");
			}
			if ((object)isTransformedMethod != null)
			{
				list.Add("Transform Status Detection");
			}
			if ((object)getQualityMethod != null)
			{
				list.Add("Quality Reading");
			}
			if ((object)setQualityMethod != null)
			{
				list.Add("Quality Setting");
			}
			return "Meatyceiver 2 Compatibility:\n• Version: " + DetectedVersion + "\n• API Version: " + DetectedApiVersion + "\n" + list.Count + "• Available Features: " + string.Join(", ", list.ToArray()) + "\n• Integration Status: " + (IsIntegrationEnabled() ? "Active" : "Disabled");
		}

		public static bool GetFeatureConfig(string key)
		{
			if (!featureConfigs.ContainsKey(key))
			{
				return false;
			}
			return featureConfigs[key].Value;
		}

		public static float GetChanceConfig(string key)
		{
			if (!chanceConfigs.ContainsKey(key))
			{
				return 0.02f;
			}
			return chanceConfigs[key].Value;
		}

		public static float GetMultiplierConfig(string key)
		{
			if (!multiplierConfigs.ContainsKey(key))
			{
				return 1f;
			}
			return multiplierConfigs[key].Value;
		}

		private static float CalculateTransformationChance(FVRFireArm firearm, string context)
		{
			float num = 0.02f;
			if (chanceConfigs.ContainsKey(context))
			{
				num = chanceConfigs[context].Value;
			}
			else
			{
				context = context.ToLower();
				num = (context.Contains("chaos") ? chanceConfigs["Chaos"].Value : ((context.Contains("elite") || context.Contains("boss")) ? chanceConfigs["Elite"].Value : (context.Contains("player") ? chanceConfigs["Player"].Value : (context.Contains("enemy") ? chanceConfigs["EnemyWeapon"].Value : ((!context.Contains("ally")) ? chanceConfigs["Normal"].Value : chanceConfigs["AllyWeapon"].Value)))));
			}
			float weaponCategoryMultiplier = GetWeaponCategoryMultiplier(firearm);
			float num2 = 1f;
			if (featureConfigs["UseQualityBasedChances"].Value)
			{
				num2 = GetQualityMultiplier(firearm);
			}
			float num3 = num * weaponCategoryMultiplier * num2;
			if (featureConfigs["RespectOriginalChances"].Value && (object)transformChanceProperty != null)
			{
				try
				{
					float val = (float)transformChanceProperty.GetValue(meatyceiverInstance, null);
					num3 = Math.Min(num3, val);
				}
				catch (Exception ex)
				{
					logger.LogDebug((object)("[MeatyceiverIntegration] Could not get original chance: " + ex.Message));
				}
			}
			if (featureConfigs["DebugMode"].Value)
			{
				logger.LogDebug((object)$"[MeatyceiverIntegration] Calculated chance for {((Object)firearm).name} ({context}): {num3:P2} (base: {num:P2}, category: {weaponCategoryMultiplier:F2}, quality: {num2:F2})");
			}
			return Mathf.Clamp01(num3);
		}

		private static float GetWeaponCategoryMultiplier(FVRFireArm firearm)
		{
			string text = ((Object)firearm).name.ToLower();
			if (text.Contains("pistol") || text.Contains("handgun"))
			{
				return multiplierConfigs["Pistol"].Value;
			}
			if (text.Contains("shotgun"))
			{
				return multiplierConfigs["Shotgun"].Value;
			}
			if (text.Contains("smg") || text.Contains("submachine"))
			{
				return multiplierConfigs["SMG"].Value;
			}
			if (text.Contains("sniper") || text.Contains("precision"))
			{
				return multiplierConfigs["Sniper"].Value;
			}
			if (text.Contains("lmg") || text.Contains("machinegun"))
			{
				return multiplierConfigs["LMG"].Value;
			}
			if (text.Contains("assault") || text.Contains("carbine"))
			{
				return multiplierConfigs["AssaultRifle"].Value;
			}
			if (text.Contains("rifle"))
			{
				return multiplierConfigs["Rifle"].Value;
			}
			return 1f;
		}

		private static float GetQualityMultiplier(FVRFireArm firearm)
		{
			return GetWeaponQuality(firearm) switch
			{
				WeaponQuality.Common => multiplierConfigs["CommonQuality"].Value, 
				WeaponQuality.Uncommon => multiplierConfigs["UncommonQuality"].Value, 
				WeaponQuality.Rare => multiplierConfigs["RareQuality"].Value, 
				WeaponQuality.Epic => multiplierConfigs["EpicQuality"].Value, 
				WeaponQuality.Legendary => multiplierConfigs["LegendaryQuality"].Value, 
				WeaponQuality.Artifact => multiplierConfigs["ArtifactQuality"].Value, 
				_ => 1f, 
			};
		}

		private static WeaponQuality DetectWeaponQualityFallback(FVRFireArm firearm)
		{
			string text = ((Object)firearm).name.ToLower();
			if (text.Contains("legendary") || text.Contains("mythic") || text.Contains("unique"))
			{
				return WeaponQuality.Legendary;
			}
			if (text.Contains("epic") || text.Contains("purple") || text.Contains("elite"))
			{
				return WeaponQuality.Epic;
			}
			if (text.Contains("rare") || text.Contains("blue") || text.Contains("special"))
			{
				return WeaponQuality.Rare;
			}
			if (text.Contains("uncommon") || text.Contains("green") || text.Contains("enhanced"))
			{
				return WeaponQuality.Uncommon;
			}
			return WeaponQuality.Common;
		}

		private static bool PerformTransformation(FVRFireArm firearm, string context)
		{
			if ((object)transformMethod == null)
			{
				logger.LogWarning((object)"[MeatyceiverIntegration] No transform method available");
				return false;
			}
			try
			{
				int num = 0;
				WeaponQuality weaponQuality = WeaponQuality.Common;
				List<FVRFireArmAttachment> list = new List<FVRFireArmAttachment>();
				if (featureConfigs["PreserveAmmo"].Value && (Object)(object)firearm.Magazine != (Object)null)
				{
					num = firearm.Magazine.m_numRounds;
				}
				if (featureConfigs["PreserveQuality"].Value)
				{
					weaponQuality = GetWeaponQuality(firearm);
				}
				if (featureConfigs["PreserveAttachments"].Value)
				{
					list.AddRange(((Component)firearm).GetComponentsInChildren<FVRFireArmAttachment>());
				}
				object obj = transformMethod.Invoke(meatyceiverInstance, new object[1] { firearm });
				bool flag = !(obj is bool) || (bool)obj;
				if (flag)
				{
					if (featureConfigs["PreserveAmmo"].Value && (Object)(object)firearm.Magazine != (Object)null && num > 0)
					{
						firearm.Magazine.m_numRounds = num;
					}
					if (featureConfigs["PreserveQuality"].Value && (object)setQualityMethod != null && weaponQuality > WeaponQuality.Common)
					{
						try
						{
							setQualityMethod.Invoke(meatyceiverInstance, new object[2]
							{
								firearm,
								(int)weaponQuality
							});
							QualityPreserved++;
						}
						catch (Exception ex)
						{
							logger.LogDebug((object)("[MeatyceiverIntegration] Could not preserve quality: " + ex.Message));
						}
					}
				}
				return flag;
			}
			catch (Exception ex2)
			{
				logger.LogError((object)("[MeatyceiverIntegration] Transformation failed: " + ex2.Message));
				return false;
			}
		}

		private static bool IsOnCooldown(string weaponKey)
		{
			if (!transformationCooldowns.ContainsKey(weaponKey))
			{
				return false;
			}
			DateTime dateTime = transformationCooldowns[weaponKey].AddSeconds(intConfigs["CooldownSeconds"].Value);
			return DateTime.Now < dateTime;
		}

		private static void SetCooldown(string weaponKey)
		{
			transformationCooldowns[weaponKey] = DateTime.Now;
		}

		private static void UpdateTransformationStatistics(string context, FVRFireArm firearm)
		{
			if (!TransformationsByContext.ContainsKey(context))
			{
				TransformationsByContext[context] = 0;
			}
			TransformationsByContext[context]++;
			string weaponTypeName = GetWeaponTypeName(firearm);
			if (!TransformationsByWeaponType.ContainsKey(weaponTypeName))
			{
				TransformationsByWeaponType[weaponTypeName] = 0;
			}
			TransformationsByWeaponType[weaponTypeName]++;
		}

		private static string GetWeaponTypeName(FVRFireArm firearm)
		{
			string text = ((Object)firearm).name.ToLower();
			if (text.Contains("pistol") || text.Contains("handgun"))
			{
				return "Pistol";
			}
			if (text.Contains("shotgun"))
			{
				return "Shotgun";
			}
			if (text.Contains("smg") || text.Contains("submachine"))
			{
				return "SMG";
			}
			if (text.Contains("sniper"))
			{
				return "Sniper";
			}
			if (text.Contains("lmg"))
			{
				return "LMG";
			}
			if (text.Contains("rifle"))
			{
				return "Rifle";
			}
			return "Unknown";
		}

		private static void PlayTransformationSound(Vector3 position)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				AudioManager audioManager = Object.FindObjectOfType<AudioManager>();
				if ((Object)(object)audioManager != (Object)null)
				{
					audioManager.PlayWeaponSpawnSound("transformation", position);
				}
				else
				{
					logger.LogDebug((object)$"[MeatyceiverIntegration] Playing transformation sound at {position}");
				}
			}
			catch (Exception ex)
			{
				logger.LogDebug((object)("[MeatyceiverIntegration] Could not play transformation sound: " + ex.Message));
			}
		}

		private static void ShowTransformationParticles(Vector3 position)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EffectsManager effectsManager = Object.FindObjectOfType<EffectsManager>();
				if ((Object)(object)effectsManager != (Object)null)
				{
					logger.LogDebug((object)$"[MeatyceiverIntegration] Showing transformation particles at {position}");
				}
				else
				{
					logger.LogDebug((object)$"[MeatyceiverIntegration] Showing transformation particles at {position}");
				}
			}
			catch (Exception ex)
			{
				logger.LogDebug((object)("[MeatyceiverIntegration] Could not show transformation particles: " + ex.Message));
			}
		}

		private static string GetWeaponKey(FVRFireArm firearm)
		{
			try
			{
				if (((FVRPhysicalObject)firearm).ObjectWrapper?.ItemID != null)
				{
					return ((FVRPhysicalObject)firearm).ObjectWrapper.ItemID;
				}
				return ((Object)((Component)firearm).gameObject).GetInstanceID().ToString();
			}
			catch
			{
				return ((object)firearm).GetHashCode().ToString();
			}
		}

		private static void CacheResult(string weaponKey, bool result)
		{
			if (featureConfigs["EnableCaching"].Value)
			{
				transformationCache[weaponKey] = result;
				transformationTimes[weaponKey] = DateTime.Now;
				if (transformationCache.Count > intConfigs["MaxCacheSize"].Value)
				{
					CleanOldCacheEntries(forceClear: true);
				}
				if ((DateTime.Now - lastCacheClear).TotalMinutes > 5.0)
				{
					CleanOldCacheEntries();
					lastCacheClear = DateTime.Now;
				}
			}
		}

		private static void CleanOldCacheEntries(bool forceClear = false)
		{
			DateTime dateTime = DateTime.Now.AddMinutes(-intConfigs["CacheLifetimeMinutes"].Value);
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, DateTime> transformationTime in transformationTimes)
			{
				if (transformationTime.Value < dateTime || forceClear)
				{
					list.Add(transformationTime.Key);
				}
			}
			if (forceClear && list.Count < transformationCache.Count / 2)
			{
				IEnumerable<KeyValuePair<string, DateTime>> source = transformationTimes.OrderBy<KeyValuePair<string, DateTime>, DateTime>((KeyValuePair<string, DateTime> kvp) => kvp.Value).Take(transformationCache.Count / 2);
				list.AddRange(source.Select((KeyValuePair<string, DateTime> kvp) => kvp.Key));
			}
			foreach (string item in list)
			{
				transformationCache.Remove(item);
				transformationTimes.Remove(item);
				weaponQualities.Remove(item);
			}
			if (list.Count > 0)
			{
				logger.LogDebug((object)$"[MeatyceiverIntegration] Cleaned {list.Count} cache entries");
			}
		}
	}
	public static class StovepipeIntegrationManager
	{
		public enum MalfunctionType
		{
			None,
			Stovepipe,
			DoubleFeed,
			FailureToFeed,
			FailureToEject,
			FailureToFire,
			HangFire,
			SquibLoad,
			SlamFire,
			OutOfBattery,
			BrokenExtractor,
			DirtyGun,
			AmmoIssue
		}

		public enum WeaponCategory
		{
			Unknown,
			Pistol,
			Rifle,
			Shotgun,
			SMG,
			LMG,
			AssaultRifle,
			Sniper,
			Revolver,
			Bolt,
			Pump
		}

		private static ManualLogSource logger;

		private static bool initialized = false;

		private static Type stovepipeType;

		private static object stovepipeInstance;

		private static MethodInfo forceMalfunctionMethod;

		private static MethodInfo checkCompatibilityMethod;

		private static MethodInfo getJamStateMethod;

		private static MethodInfo clearJamMethod;

		private static MethodInfo setJamChanceMethod;

		private static MethodInfo getMalfunctionTypeMethod;

		private static PropertyInfo malfunctionChanceProperty;

		private static PropertyInfo jamStateProperty;

		private static FieldInfo enabledField;

		private static ConfigFile config;

		private static Dictionary<string, ConfigEntry<float>> chanceConfigs;

		private static Dictionary<string, ConfigEntry<bool>> featureConfigs;

		private static Dictionary<string, ConfigEntry<float>> multiplierConfigs;

		private static Dictionary<string, ConfigEntry<int>> intConfigs;

		private static readonly Dictionary<string, bool> jamCapabilityCache = new Dictionary<string, bool>();

		private static readonly Dictionary<string, DateTime> lastJamTimes = new Dictionary<string, DateTime>();

		private static readonly Dictionary<string, MalfunctionType> lastMalfunctionTypes = new Dictionary<string, MalfunctionType>();

		private static readonly Dictionary<string, DateTime> jamCooldowns = new Dictionary<string, DateTime>();

		private static DateTime lastCacheClear = DateTime.Now;

		private const string STOVEPIPE_GUID = "dll.stovepipe";

		private const string STOVEPIPE_LEGACY_GUID = "stovepipe.weapon.jams";

		private const string STOVEPIPE_ALPHA_GUID = "stovepipe.alpha";

		private const string STOVEPIPE_BETA_GUID = "stovepipe.beta";

		public static bool IsStovepipeAvailable { get; private set; } = false;

		public static string DetectedVersion { get; private set; } = "Unknown";

		public static string DetectedApiVersion { get; private set; } = "Unknown";

		public static int TotalMalfunctionAttempts { get; private set; } = 0;

		public static int SuccessfulMalfunctions { get; private set; } = 0;

		public static int CachedResults { get; private set; } = 0;

		public static int CooldownBlocked { get; private set; } = 0;

		public static int JamsCleared { get; private set; } = 0;

		public static Dictionary<string, int> MalfunctionsByContext { get; private set; } = new Dictionary<string, int>();

		public static Dictionary<string, int> MalfunctionsByWeaponType { get; private set; } = new Dictionary<string, int>();

		public static Dictionary<MalfunctionType, int> MalfunctionsByType { get; private set; } = new Dictionary<MalfunctionType, int>();

		public static void Initialize(ManualLogSource logSource, ConfigFile configFile)
		{
			if (!initialized)
			{
				logger = logSource;
				config = configFile;
				logger.LogInfo((object)"[StovepipeIntegration] Initializing Stovepipe integration...");
				InitializeConfiguration();
				DetectStovepipe();
				if (IsStovepipeAvailable)
				{
					CacheStovepipeMethods();
					InitializeCompatibilityLayer();
					logger.LogInfo((object)("[StovepipeIntegration] Successfully initialized with Stovepipe " + DetectedVersion + " (API: " + DetectedApiVersion + ")"));
				}
				else
				{
					logger.LogInfo((object)"[StovepipeIntegration] Stovepipe not detected - integration disabled");
				}
				initialized = true;
			}
		}

		private static void InitializeConfiguration()
		{
			chanceConfigs = new Dictionary<string, ConfigEntry<float>>();
			featureConfigs = new Dictionary<string, ConfigEntry<bool>>();
			multiplierConfigs = new Dictionary<string, ConfigEntry<float>>();
			intConfigs = new Dictionary<string, ConfigEntry<int>>();
			chanceConfigs["Normal"] = config.Bind<float>("Stovepipe", "ChanceNormal", 0.01f, "Normal malfunction chance");
			chanceConfigs["Combat"] = config.Bind<float>("Stovepipe", "ChanceCombat", 0.03f, "Combat stress malfunction chance");
			chanceConfigs["Dirty"] = config.Bind<float>("Stovepipe", "ChanceDirty", 0.08f, "Dirty weapon malfunction chance");
			chanceConfigs["Player"] = config.Bind<float>("Stovepipe", "ChancePlayer", 0.02f, "Player weapon malfunction chance");
			chanceConfigs["Enemy"] = config.Bind<float>("Stovepipe", "ChanceEnemy", 0.04f, "Enemy weapon malfunction chance");
			chanceConfigs["Ally"] = config.Bind<float>("Stovepipe", "ChanceAlly", 0.015f, "Ally weapon malfunction chance");
			chanceConfigs["Elite"] = config.Bind<float>("Stovepipe", "ChanceElite", 0.005f, "Elite weapon malfunction chance");
			chanceConfigs["Boss"] = config.Bind<float>("Stovepipe", "ChanceBoss", 0.001f, "Boss weapon malfunction chance");
			chanceConfigs["WornOut"] = config.Bind<float>("Stovepipe", "ChanceWornOut", 0.12f, "Worn out weapon malfunction chance");
			chanceConfigs["Overheated"] = config.Bind<float>("Stovepipe", "ChanceOverheated", 0.06f, "Overheated weapon malfunction chance");
			multiplierConfigs["Pistol"] = config.Bind<float>("Stovepipe", "PistolMultiplier", 1.2f, "Pistol malfunction multiplier");
			multiplierConfigs["Rifle"] = config.Bind<float>("Stovepipe", "RifleMultiplier", 0.8f, "Rifle malfunction multiplier");
			multiplierConfigs["Shotgun"] = config.Bind<float>("Stovepipe", "ShotgunMultiplier", 0.6f, "Shotgun malfunction multiplier");
			multiplierConfigs["SMG"] = config.Bind<float>("Stovepipe", "SMGMultiplier", 1.4f, "SMG malfunction multiplier");
			multiplierConfigs["LMG"] = config.Bind<float>("Stovepipe", "LMGMultiplier", 1.1f, "LMG malfunction multiplier");
			multiplierConfigs["AssaultRifle"] = config.Bind<float>("Stovepipe", "AssaultRifleMultiplier", 0.9f, "Assault rifle malfunction multiplier");
			multiplierConfigs["Sniper"] = config.Bind<float>("Stovepipe", "SniperMultiplier", 0.7f, "Sniper rifle malfunction multiplier");
			multiplierConfigs["Revolver"] = config.Bind<float>("Stovepipe", "RevolverMultiplier", 0.3f, "Revolver malfunction multiplier");
			multiplierConfigs["Bolt"] = config.Bind<float>("Stovepipe", "BoltMultiplier", 0.2f, "Bolt action malfunction multiplier");
			multiplierConfigs["Pump"] = config.Bind<float>("Stovepipe", "PumpMultiplier", 0.4f, "Pump action malfunction multiplier");
			multiplierConfigs["StovepipeChance"] = config.Bind<float>("Stovepipe", "StovepipeChance", 1.5f, "Stovepipe jam chance multiplier");
			multiplierConfigs["DoubleFeedChance"] = config.Bind<float>("Stovepipe", "DoubleFeedChance", 1f, "Double feed chance multiplier");
			multiplierConfigs["FailureToFeedChance"] = config.Bind<float>("Stovepipe", "FailureToFeedChance", 1.2f, "Failure to feed chance multiplier");
			multiplierConfigs["FailureToEjectChance"] = config.Bind<float>("Stovepipe", "FailureToEjectChance", 1.1f, "Failure to eject chance multiplier");
			multiplierConfigs["FailureToFireChance"] = config.Bind<float>("Stovepipe", "FailureToFireChance", 0.8f, "Failure to fire chance multiplier");
			multiplierConfigs["HangFireChance"] = config.Bind<float>("Stovepipe", "HangFireChance", 0.3f, "Hang fire chance multiplier");
			featureConfigs["Enabled"] = config.Bind<bool>("Stovepipe", "Enabled", true, "Enable Stovepipe integration");
			featureConfigs["AutoClearJams"] = config.Bind<bool>("Stovepipe", "AutoClearJams", false, "Automatically clear jams after delay");
			featureConfigs["ContextualMalfunctions"] = config.Bind<bool>("Stovepipe", "ContextualMalfunctions", true, "Use contextual malfunction logic");
			featureConfigs["RealisticJamTypes"] = config.Bind<bool>("Stovepipe", "RealisticJamTypes", true, "Use realistic jam types based on weapon");
			featureConfigs["EnableCooldowns"] = config.Bind<bool>("Stovepipe", "EnableCooldowns", true, "Enable jam cooldowns");
			featureConfigs["EnableCaching"] = config.Bind<bool>("Stovepipe", "EnableCaching", true, "Enable jam capability caching");
			featureConfigs["DirtAccumulation"] = config.Bind<bool>("Stovepipe", "DirtAccumulation", true, "Enable dirt accumulation system");
			featureConfigs["HeatBuildup"] = config.Bind<bool>("Stovepipe", "HeatBuildup", true, "Enable heat buildup system");
			featureConfigs["AmmoQualityAffectsJams"] = config.Bind<bool>("Stovepipe", "AmmoQualityAffectsJams", true, "Ammunition quality affects jam chance");
			featureConfigs["WeaponConditionTracking"] = config.Bind<bool>("Stovepipe", "WeaponConditionTracking", true, "Track weapon condition for jam chances");
			featureConfigs["PlayMalfunctionSounds"] = config.Bind<bool>("Stovepipe", "PlayMalfunctionSounds", true, "Play malfunction sound effects");
			featureConfigs["ShowMalfunctionParticles"] = config.Bind<bool>("Stovepipe", "ShowMalfunctionParticles", true, "Show malfunction particle effects");
			featureConfigs["EnableBatchJamming"] = config.Bind<bool>("Stovepipe", "EnableBatchJamming", true, "Enable batch jamming support");
			featureConfigs["DebugMode"] = config.Bind<bool>("Stovepipe", "DebugMode", false, "Enable debug mode");
			featureConfigs["VerboseLogging"] = config.Bind<bool>("Stovepipe", "VerboseLogging", false, "Enable verbose logging");
			intConfigs["JamCooldownSeconds"] = config.Bind<int>("Stovepipe", "JamCooldownSeconds", 5, "Cooldown between jams (seconds)");
			intConfigs["AutoClearDelaySeconds"] = config.Bind<int>("Stovepipe", "AutoClearDelaySeconds", 15, "Auto clear jam delay (seconds)");
			intConfigs["CacheLifetimeMinutes"] = config.Bind<int>("Stovepipe", "CacheLifetimeMinutes", 15, "Cache entry lifetime in minutes");
			intConfigs["MaxCacheSize"] = config.Bind<int>("Stovepipe", "MaxCacheSize", 500, "Maximum number of cached entries");
			intConfigs["BatchSize"] = config.Bind<int>("Stovepipe", "BatchSize", 5, "Maximum weapons to jam in a single batch");
			intConfigs["MaxDirtLevel"] = config.Bind<int>("Stovepipe", "MaxDirtLevel", 100, "Maximum dirt accumulation level");
			intConfigs["MaxHeatLevel"] = config.Bind<int>("Stovepipe", "MaxHeatLevel", 100, "Maximum heat buildup level");
		}

		private static void DetectStovepipe()
		{
			try
			{
				Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
				if (pluginInfos.ContainsKey("dll.stovepipe"))
				{
					IsStovepipeAvailable = true;
					DetectedVersion = pluginInfos["dll.stovepipe"].Metadata.Version.ToString();
					logger.LogInfo((object)("[StovepipeIntegra