Decompiled source of Matty Fixes Experimental v1.1.39

BepInEx/plugins/Matty's Fixes.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using HarmonyLib;
using HarmonyLib.Public.Patching;
using InjectionLibrary.Attributes;
using JetBrains.Annotations;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLevelLoader;
using LethalLib.Modules;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using MattyFixes.Dependency;
using MattyFixes.Interfaces;
using MattyFixes.Utils;
using MattyFixes.Utils.IL;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Bindings;
using UnityEngine.Rendering;
using VertexLibrary;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RequiresInjections]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("mattymatty")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.39")]
[assembly: AssemblyInformationalVersion("1.1.39+00dae62a702e974a9308bf9c83b3a72349b56425")]
[assembly: AssemblyProduct("Matty's Fixes")]
[assembly: AssemblyTitle("Matty's Fixes - Plugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.39.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MattyFixes
{
	[BepInPlugin("mattymatty.MattyFixes", "Matty's Fixes", "1.1.39")]
	[BepInDependency("com.github.lethalcompanymodding.vertexlibrary", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class MattyFixes : BaseUnityPlugin
	{
		internal static class PluginConfig
		{
			internal static class ReadableMeshes
			{
				internal static ConfigEntry<bool> Enabled;
			}

			internal static class Particles
			{
				internal enum LightningType
				{
					Vanilla,
					Fixed,
					Alternate
				}

				internal static ConfigEntry<LightningType> Lightning;

				internal static ConfigEntry<bool> FixFlies;
			}

			internal static class BadgeFixes
			{
				internal static ConfigEntry<bool> Enabled;
			}

			internal static class CupBoard
			{
				internal static ConfigEntry<bool> Enabled;

				internal static ConfigEntry<float> Tolerance;

				internal static ConfigEntry<float> Shift;
			}

			internal static class Radar
			{
				internal static ConfigEntry<bool> Enabled;

				internal static ConfigEntry<bool> RemoveDeleted;

				internal static ConfigEntry<bool> RemoveOnShip;
			}

			internal static class ItemClipping
			{
				internal static ConfigEntry<bool> Enabled;

				internal static ConfigEntry<bool> RotateOnSpawn;

				internal static ConfigEntry<float> VerticalOffset;

				internal static ConfigEntry<string> ManualOffsets;

				internal static readonly Dictionary<string, float> ManualOffsetMap = new Dictionary<string, float>(StringComparer.InvariantCultureIgnoreCase);

				internal static readonly Dictionary<Item, ItemRotationConfig> ItemRotations = new Dictionary<Item, ItemRotationConfig>();
			}

			internal static class OutOfBounds
			{
				internal static ConfigEntry<bool> Enabled;

				internal static ConfigEntry<float> VerticalOffset;

				internal static ConfigEntry<bool> SpawnInFurniture;
			}

			internal static class AlternateLightingParticle
			{
			}

			internal static class Debug
			{
				internal static ConfigEntry<LogLevel> VerboseMeshes;

				internal static ConfigEntry<LogLevel> VerboseCupboard;

				internal static ConfigEntry<LogLevel> VerboseItems;
			}

			internal static void Init()
			{
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Expected O, but got Unknown
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Expected O, but got Unknown
				//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Expected O, but got Unknown
				//IL_0224: Unknown result type (might be due to invalid IL or missing references)
				//IL_022e: Expected O, but got Unknown
				ConfigFile config = ((BaseUnityPlugin)Instance).Config;
				ReadableMeshes.Enabled = config.Bind<bool>("ReadableMeshes", "enabled", true, "convert all meshes to readable at runtime");
				Particles.Lightning = config.Bind<Particles.LightningType>("Particles", "fix_lightning", Particles.LightningType.Fixed, "change rendering of the Lightning particles:\r\n- Vanilla: no changes!\r\n- Fixed: show lightning particles as dev intended! \r\n- Alternate: particles will show in a sphere around the item");
				Particles.FixFlies = config.Bind<bool>("Particles", "fix_flies", true, "show crawling bugs particles as dev intended! ( affects Ear, Hand and Thigh )");
				BadgeFixes.Enabled = config.Bind<bool>("BadgeFixes", "enabled", true, "show correct level tag");
				CupBoard.Enabled = config.Bind<bool>("CupBoard", "enabled", true, "prevent items inside or above the Storage Closet from falling to the ground");
				CupBoard.Tolerance = config.Bind<float>("CupBoard", "tolerance", 0.05f, new ConfigDescription("how loosely \"close\" the items have to be to the top of the closet for them to count X/Z", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
				CupBoard.Shift = config.Bind<float>("CupBoard", "shift", 0.1f, new ConfigDescription("how much move the items inside the closet on load ( only if ItemClippingFix disabled )", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
				Radar.Enabled = config.Bind<bool>("Radar", "enabled", true, "remove orphan radar icons from deleted/collected scrap");
				Radar.RemoveDeleted = config.Bind<bool>("Radar", "deleted_scrap", true, "remove orphan radar icons from deleted scrap ( company building )");
				Radar.RemoveOnShip = config.Bind<bool>("Radar", "ship_loot", true, "remove orphan radar icons from scrap on the ship in a recently created game");
				ItemClipping.Enabled = config.Bind<bool>("ItemClipping", "enabled", true, "fix rotation and height of various items when on the Ground");
				ItemClipping.RotateOnSpawn = config.Bind<bool>("ItemClipping", "rotate_on_spawn", true, "fix rotation of newly spawned items");
				ItemClipping.VerticalOffset = config.Bind<float>("ItemClipping", "vertical_offset", 0f, new ConfigDescription("additional y offset for items on the ground", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>()));
				ItemClipping.ManualOffsets = config.Bind<string>("ItemClipping", "manual_offsets", "", "y offset for items on the ground\nDictionary Format: '[key]:[value],[key2]:[value2]'\neg: `Vanilla/Ammo:0.0`");
				OutOfBounds.Enabled = config.Bind<bool>("OutOfBounds", "enabled", true, "prevent items from falling below the ship");
				OutOfBounds.VerticalOffset = config.Bind<float>("OutOfBounds", "vertical_offset", 0.01f, new ConfigDescription("vertical offset to apply to objects on load to prevent them from clipping into the floor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 1f), Array.Empty<object>()));
				OutOfBounds.SpawnInFurniture = config.Bind<bool>("OutOfBounds", "spawn_in_furniture", true, "Fix items generating inside furniture ( eg: lamps inside the kitchen counter )");
				Debug.VerboseMeshes = config.Bind<LogLevel>("Debug", "Mesh Verbosity Level", (LogLevel)0, "Print A LOT more logs about Meshes");
				Debug.VerboseCupboard = config.Bind<LogLevel>("Debug", "Cupboard Verbosity Level", (LogLevel)0, "Print A LOT more logs about Cupboard detection");
				Debug.VerboseItems = config.Bind<LogLevel>("Debug", "Item Verbosity Level", (LogLevel)0, "Print A LOT more logs about Cupboard detection");
				string value = ItemClipping.ManualOffsets.Value;
				string[] array = value.Split(',');
				foreach (string text in array)
				{
					string[] array2 = text.Split(':');
					if (array2.Length > 1)
					{
						string key = array2[0].Trim();
						if (float.TryParse(array2[1], NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.InvariantInfo, out var result))
						{
							ItemClipping.ManualOffsetMap.Add(key, result);
						}
					}
				}
				if (LethalConfigProxy.Enabled)
				{
					LethalConfigProxy.AddButton("Cleanup", "Clear old entries", "remove unused entries in the config file\n(IF RUN FROM MENU WILL DELETE ALL ITEM OFFSETS!!)", "Clean&Save", RemoveOrphans);
					LethalConfigProxy.AddConfig(ReadableMeshes.Enabled, requiresRestart: true);
					LethalConfigProxy.AddConfig<Particles.LightningType>(Particles.Lightning, requiresRestart: true);
					LethalConfigProxy.AddConfig(Particles.FixFlies, requiresRestart: true);
					LethalConfigProxy.AddConfig(BadgeFixes.Enabled, requiresRestart: true);
					LethalConfigProxy.AddConfig(CupBoard.Enabled);
					LethalConfigProxy.AddConfig(CupBoard.Tolerance);
					LethalConfigProxy.AddConfig(CupBoard.Shift);
					LethalConfigProxy.AddConfig(Radar.Enabled);
					LethalConfigProxy.AddConfig(Radar.RemoveDeleted);
					LethalConfigProxy.AddConfig(Radar.RemoveOnShip);
					LethalConfigProxy.AddConfig(ItemClipping.Enabled);
					LethalConfigProxy.AddConfig(ItemClipping.RotateOnSpawn);
					LethalConfigProxy.AddConfig(ItemClipping.VerticalOffset);
					LethalConfigProxy.AddConfig(ItemClipping.ManualOffsets, requiresRestart: true);
					LethalConfigProxy.AddConfig(OutOfBounds.Enabled, requiresRestart: true);
					LethalConfigProxy.AddConfig(OutOfBounds.VerticalOffset);
					LethalConfigProxy.AddConfig(OutOfBounds.SpawnInFurniture, requiresRestart: true);
					LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseMeshes, requiresRestart: false);
					LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseCupboard, requiresRestart: false);
					LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseItems, requiresRestart: false);
				}
			}

			internal static void RemoveOrphans()
			{
				ConfigFile config = ((BaseUnityPlugin)Instance).Config;
				PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
				Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null);
				dictionary.Clear();
				config.Save();
			}
		}

		internal readonly struct ItemRotationConfig
		{
			public Vector3 Original { get; }

			public ConfigEntry<string> Config { get; }

			public ItemRotationConfig(Vector3 original, ConfigEntry<string> config)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				Original = original;
				Config = config;
			}
		}

		public const string GUID = "mattymatty.MattyFixes";

		public const string NAME = "Matty's Fixes";

		public const string VERSION = "1.1.39";

		internal static ManualLogSource Log;

		private static int? _visibleLayerMask;

		internal static Harmony Harmony { get; private set; }

		internal static HashSet<Hook> Hooks { get; } = new HashSet<Hook>();


		internal static MattyFixes Instance { get; private set; }

		public static int VisibleLayerMask
		{
			get
			{
				int valueOrDefault = _visibleLayerMask.GetValueOrDefault();
				if (!_visibleLayerMask.HasValue)
				{
					valueOrDefault = LayerMask.GetMask(new string[13]
					{
						"Default", "Player", "Water", "Props", "Room", "InteractableObject", "Foliage", "PhysicsObject", "Enemies", "PlayerRagdoll",
						"MapHazards", "MiscLevelGeometry", "Terrain"
					});
					_visibleLayerMask = valueOrDefault;
				}
				return _visibleLayerMask.Value;
			}
		}

		private void Awake()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				if (LobbyCompatibilityChecker.Enabled)
				{
					LobbyCompatibilityChecker.Init();
				}
				Log.LogInfo((object)"Initializing Configs");
				PluginConfig.Init();
				Log.LogInfo((object)"Patching Methods");
				Harmony = new Harmony("mattymatty.MattyFixes");
				Harmony.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)"Matty's Fixes v1.1.39 Loaded!");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Exception while initializing: \n" + ex));
			}
		}

		internal static void VerboseMeshLog(LogType logLevel, Func<string> message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			LogLevel val;
			if ((int)logLevel <= 128)
			{
				if ((int)logLevel <= 8)
				{
					if ((int)logLevel != 2)
					{
						if ((int)logLevel != 4)
						{
							if ((int)logLevel != 8)
							{
								goto IL_00a6;
							}
							val = (LogLevel)4;
						}
						else
						{
							val = (LogLevel)2;
						}
					}
					else
					{
						val = (LogLevel)1;
					}
					goto IL_00a8;
				}
				if ((int)logLevel <= 32)
				{
					if ((int)logLevel == 16 || (int)logLevel == 32)
					{
						goto IL_0097;
					}
				}
				else if ((int)logLevel == 64 || (int)logLevel == 128)
				{
					goto IL_0097;
				}
			}
			else if ((int)logLevel <= 512)
			{
				if ((int)logLevel == 240)
				{
					goto IL_0097;
				}
				if ((int)logLevel == 256 || (int)logLevel == 512)
				{
					goto IL_009c;
				}
			}
			else if ((int)logLevel <= 2048)
			{
				if ((int)logLevel == 1024 || (int)logLevel == 2048)
				{
					goto IL_009c;
				}
			}
			else
			{
				if ((int)logLevel == 3840)
				{
					goto IL_009c;
				}
				if ((int)logLevel == 4094)
				{
					val = (LogLevel)63;
					goto IL_00a8;
				}
			}
			goto IL_00a6;
			IL_0097:
			val = (LogLevel)16;
			goto IL_00a8;
			IL_00a6:
			val = (LogLevel)0;
			goto IL_00a8;
			IL_009c:
			val = (LogLevel)32;
			goto IL_00a8;
			IL_00a8:
			LogLevel logLevel2 = val;
			VerboseMeshLog(logLevel2, message);
		}

		internal static void VerboseMeshLog(LogLevel logLevel, Func<string> message)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if ((PluginConfig.Debug.VerboseMeshes.Value & logLevel) != 0)
			{
				Log.Log(logLevel, (object)message());
			}
		}

		internal static void VerboseCupboardLog(LogLevel logLevel, Func<string> message)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if ((PluginConfig.Debug.VerboseCupboard.Value & logLevel) != 0)
			{
				Log.Log(logLevel, (object)message());
			}
		}

		internal static void VerboseItemsLog(LogLevel logLevel, Func<string> message)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if ((PluginConfig.Debug.VerboseItems.Value & logLevel) != 0)
			{
				Log.Log(logLevel, (object)message());
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "mattymatty.MattyFixes";

		public const string PLUGIN_NAME = "Matty's Fixes";

		public const string PLUGIN_VERSION = "1.1.39";
	}
}
namespace MattyFixes.Utils
{
	public static class ItemCategory
	{
		public enum ItemType
		{
			Unknown,
			Vanilla,
			Modded
		}

		private static readonly Regex ConfigFilterRegex = new Regex("[\\n\\t\\\\\\'\\[\\]]");

		[NotNull]
		public static string GetPath(this Item item)
		{
			string mattyFixes_Path = ((IInjectedItem)item).MattyFixes_Path;
			if (mattyFixes_Path != null)
			{
				return mattyFixes_Path;
			}
			ItemType itemType = ItemType.Unknown;
			mattyFixes_Path = item.ComputePath("Unknown");
			if (DawnLibProxy.Enabled)
			{
				string path;
				ItemType itemType2 = DawnLibProxy.DefineItem(item, out path);
				if (itemType <= itemType2)
				{
					itemType = itemType2;
					mattyFixes_Path = path;
				}
			}
			((IInjectedItem)item).MattyFixes_ItemType = itemType;
			((IInjectedItem)item).MattyFixes_Path = mattyFixes_Path;
			return mattyFixes_Path;
		}

		public static string ComputePath(this Item item, [NotNull] string library, [NotNull] params string[] path)
		{
			List<string> list = new List<string>(2 + path.Length);
			list.Add(library);
			list.AddRange(path);
			list.Add(item.itemName ?? ((Object)item).name);
			return string.Join('/', list.Select((string p) => string.Join("_", p.Split(Path.GetInvalidPathChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.')).ToArray()).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
		}

		public static string SanitizeForConfig(string input)
		{
			return ConfigFilterRegex.Replace(input, "").Trim();
		}
	}
	public static class NgoUtils
	{
		private static readonly MethodInfo BeginSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendClientRpc", (Type[])null, (Type[])null);

		private static readonly MethodInfo BeginSendServerRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendServerRpc", (Type[])null, (Type[])null);

		private static readonly __RpcExecStage ClientRpcStage;

		private static readonly __RpcExecStage ServerRpcStage;

		public static bool IsRPCClientStage(this NetworkBehaviour self)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = self.NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return false;
			}
			if (self.__rpc_exec_stage != ClientRpcStage || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return false;
			}
			return true;
		}

		public static bool IsRPCServerStage(this NetworkBehaviour self)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = self.NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return false;
			}
			if (self.__rpc_exec_stage != ServerRpcStage || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return false;
			}
			return true;
		}

		internal static bool TryGetRpcID(this MethodInfo methodInfo, out uint rpcID)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Collection<Instruction> instructions = PatchManager.GetMethodPatcher((MethodBase)methodInfo).CopyOriginal().Definition.Body.Instructions;
			rpcID = 0u;
			for (int i = 0; i < instructions.Count; i++)
			{
				if (instructions[i].OpCode == OpCodes.Ldc_I4 && instructions[i - 1].OpCode == OpCodes.Ldarg_0)
				{
					rpcID = (uint)(int)instructions[i].Operand;
				}
				if (!(instructions[i].OpCode != OpCodes.Call))
				{
					object operand = instructions[i].Operand;
					MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val != null && (Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendClientRpc) || Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendServerRpc)))
					{
						MattyFixes.Log.LogDebug((object)$"Rpc Id found for {methodInfo.Name}: {rpcID}U");
						return true;
					}
				}
			}
			MattyFixes.Log.LogFatal((object)("Cannot find Rpc ID for " + methodInfo.Name));
			return false;
		}

		static NgoUtils()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			string unityVersion = Application.unityVersion;
			__RpcExecStage clientRpcStage = ((!(unityVersion == "2022.3.9f1")) ? ((__RpcExecStage)1) : ((__RpcExecStage)2));
			ClientRpcStage = clientRpcStage;
			string unityVersion2 = Application.unityVersion;
			clientRpcStage = ((!(unityVersion2 == "2022.3.9f1")) ? ((__RpcExecStage)1) : ((__RpcExecStage)1));
			ServerRpcStage = clientRpcStage;
		}
	}
	public static class ReflectionUtils
	{
		internal static Delegate FastGetter([NotNull("ArgumentNullException")] this FieldInfo field)
		{
			if ((object)field == null)
			{
				throw new ArgumentNullException("field");
			}
			string name = field.ReflectedType.FullName + ".get_" + field.Name;
			DynamicMethod dynamicMethod = new DynamicMethod(name, field.FieldType, new Type[1] { field.DeclaringType }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (field.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldsfld, field);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldfld, field);
			}
			iLGenerator.Emit(OpCodes.Ret);
			if (field.IsStatic)
			{
				return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.FieldType));
			}
			return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.DeclaringType, field.FieldType));
		}

		internal static Delegate FastSetter([NotNull("ArgumentNullException")] this FieldInfo field)
		{
			if ((object)field == null)
			{
				throw new ArgumentNullException("field");
			}
			string name = field.ReflectedType.FullName + ".get_" + field.Name;
			DynamicMethod dynamicMethod = new DynamicMethod(name, field.FieldType, new Type[2] { field.DeclaringType, field.FieldType }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (field.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stsfld, field);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stfld, field);
			}
			iLGenerator.Emit(OpCodes.Ldarg_1);
			iLGenerator.Emit(OpCodes.Ret);
			if (field.IsStatic)
			{
				return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.FieldType, field.FieldType));
			}
			return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.DeclaringType, field.FieldType, field.FieldType));
		}
	}
}
namespace MattyFixes.Utils.IL
{
	internal class ILInjector
	{
		[CompilerGenerated]
		private sealed class <GetRelativeInstructions>d__34 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			public ILInjector <>4__this;

			private int offset;

			public int <>3__offset;

			private int size;

			public int <>3__size;

			private int <i>5__2;

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

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

			[DebuggerHidden]
			public <GetRelativeInstructions>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

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

			private bool MoveNext()
			{
				int num = <>1__state;
				ILInjector iLInjector = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < size)
				{
					<>2__current = iLInjector.instructions[iLInjector.index + offset + <i>5__2];
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<GetRelativeInstructions>d__34 <GetRelativeInstructions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetRelativeInstructions>d__ = this;
				}
				else
				{
					<GetRelativeInstructions>d__ = new <GetRelativeInstructions>d__34(0)
					{
						<>4__this = <>4__this
					};
				}
				<GetRelativeInstructions>d__.offset = <>3__offset;
				<GetRelativeInstructions>d__.size = <>3__size;
				return <GetRelativeInstructions>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private const string INVALID = "Injector is invalid";

		private List<CodeInstruction> instructions = instructions.ToList();

		private ILGenerator generator;

		private int index;

		private int matchEnd;

		public int Index
		{
			get
			{
				return index;
			}
			set
			{
				index = value;
			}
		}

		public bool IsValid
		{
			get
			{
				if (instructions != null)
				{
					return IsIndexValid(index);
				}
				return false;
			}
		}

		public CodeInstruction Instruction
		{
			get
			{
				if (!IsIndexInRange(index))
				{
					return null;
				}
				return instructions[index];
			}
			set
			{
				if (!IsIndexInRange(index))
				{
					throw new InvalidOperationException($"Current index {index} is out of range of instruction count {instructions.Count}");
				}
				instructions[index] = value;
			}
		}

		public CodeInstruction LastMatchedInstruction
		{
			get
			{
				int num = matchEnd - 1;
				if (!IsIndexInRange(num))
				{
					return null;
				}
				return instructions[num];
			}
			set
			{
				int num = matchEnd - 1;
				if (!IsIndexInRange(num))
				{
					throw new InvalidOperationException($"Last matched index {index} is out of range of instruction count {instructions.Count}");
				}
				instructions[num] = value;
			}
		}

		public ICollection<CodeInstruction> Instructions => instructions.AsReadOnly();

		public ILInjector(IEnumerable<CodeInstruction> instructions, ILGenerator generator = null)
		{
			this.generator = generator;
			matchEnd = -1;
			base..ctor();
		}

		public ILInjector GoToStart()
		{
			matchEnd = index;
			index = 0;
			return this;
		}

		public ILInjector GoToEnd()
		{
			matchEnd = index;
			index = instructions.Count;
			return this;
		}

		public ILInjector Forward(int offset)
		{
			if (!IsValid)
			{
				return this;
			}
			matchEnd = index;
			index = Math.Clamp(index + offset, -1, instructions.Count);
			return this;
		}

		public ILInjector Back(int offset)
		{
			return Forward(-offset);
		}

		private void MarkInvalid()
		{
			index = -1;
			matchEnd = -1;
		}

		private void Search(bool forward, ILMatcher[] predicates)
		{
			if (!IsValid)
			{
				return;
			}
			int num = 1;
			if (!forward)
			{
				num = -1;
				index--;
			}
			while (forward ? (index < instructions.Count) : (index >= 0))
			{
				if (forward && index + predicates.Length > instructions.Count)
				{
					index = instructions.Count;
					break;
				}
				int i;
				for (i = 0; i < predicates.Length && predicates[i].Matches(instructions[index + i]); i++)
				{
				}
				if (i == predicates.Length)
				{
					matchEnd = index + i;
					return;
				}
				index += num;
			}
			MarkInvalid();
		}

		public ILInjector Find(params ILMatcher[] predicates)
		{
			Search(forward: true, predicates);
			return this;
		}

		public ILInjector ReverseFind(params ILMatcher[] predicates)
		{
			Search(forward: false, predicates);
			return this;
		}

		public ILInjector GoToPush(int popIndex)
		{
			if (!IsValid)
			{
				return this;
			}
			matchEnd = index;
			index--;
			int num = 0;
			while (index >= 0)
			{
				CodeInstruction instruction = instructions[index];
				num += instruction.PushCount();
				num -= instruction.PopCount();
				if (num >= popIndex)
				{
					return this;
				}
				index--;
			}
			return this;
		}

		public ILInjector SkipBranch()
		{
			if (Instruction == null)
			{
				return this;
			}
			if (!(Instruction.operand is Label label))
			{
				throw new InvalidOperationException($"Current instruction is not a branch: {Instruction}");
			}
			return FindLabel(label);
		}

		public ILInjector FindLabel(Label label)
		{
			if (label == default(Label))
			{
				return this;
			}
			matchEnd = index;
			for (index = 0; index < instructions.Count; index++)
			{
				if (instructions[index].labels.Contains(label))
				{
					return this;
				}
			}
			MarkInvalid();
			return this;
		}

		public ILInjector GoToMatchEnd()
		{
			index = matchEnd;
			return this;
		}

		public ILInjector GoToLastMatchedInstruction()
		{
			if (!IsIndexValid(matchEnd))
			{
				return this;
			}
			index = matchEnd - 1;
			return this;
		}

		private bool IsIndexValid(int index)
		{
			return index != -1;
		}

		private bool IsIndexInRange(int index)
		{
			if (index >= 0)
			{
				return index < instructions.Count;
			}
			return false;
		}

		public CodeInstruction GetRelativeInstruction(int offset)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			int num = index + offset;
			if (!IsIndexInRange(num))
			{
				throw new IndexOutOfRangeException($"Offset {offset} would read out of bounds at index {num}");
			}
			return instructions[num];
		}

		public ILInjector SetRelativeInstruction(int offset, CodeInstruction instruction)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			int num = index + offset;
			if (!IsIndexInRange(num))
			{
				throw new IndexOutOfRangeException($"Offset {offset} would write out of bounds at index {num}");
			}
			instructions[num] = instruction;
			return this;
		}

		[IteratorStateMachine(typeof(<GetRelativeInstructions>d__34))]
		public IEnumerable<CodeInstruction> GetRelativeInstructions(int offset, int size)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetRelativeInstructions>d__34(-2)
			{
				<>4__this = this,
				<>3__offset = offset,
				<>3__size = size
			};
		}

		public IEnumerable<CodeInstruction> GetRelativeInstructions(int size)
		{
			return GetRelativeInstructions(0, size);
		}

		private void GetLastMatchRangeAbsolute(out int start, out int end)
		{
			start = index;
			end = matchEnd;
			if (start > end)
			{
				int num = end;
				int num2 = start;
				start = num;
				end = num2;
			}
		}

		private void GetLastMatchRange(out int start, out int size)
		{
			GetLastMatchRangeAbsolute(out start, out var end);
			if (start < 0 || start >= instructions.Count)
			{
				throw new InvalidOperationException($"Last match range starts at invalid index {start}");
			}
			if (end < 0 || end > instructions.Count)
			{
				throw new InvalidOperationException($"Last match range ends at invalid index {end}");
			}
			size = end - start;
		}

		public List<CodeInstruction> GetLastMatch()
		{
			GetLastMatchRange(out var start, out var size);
			return instructions.GetRange(start, size);
		}

		public ILInjector DefineLabel(out Label label)
		{
			if (generator == null)
			{
				throw new InvalidOperationException("No ILGenerator was provided");
			}
			label = generator.DefineLabel();
			return this;
		}

		public ILInjector AddLabel(out Label label)
		{
			DefineLabel(out label);
			return AddLabel(label);
		}

		public ILInjector AddLabel(Label label)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Instruction = new CodeInstruction(Instruction);
			Instruction.labels.Add(label);
			return this;
		}

		public ILInjector InsertInPlace(params CodeInstruction[] instructions)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			this.instructions.InsertRange(index, instructions);
			if (matchEnd >= index)
			{
				matchEnd += instructions.Length;
			}
			return this;
		}

		public ILInjector Insert(params CodeInstruction[] instructions)
		{
			InsertInPlace(instructions);
			index += instructions.Length;
			return this;
		}

		public ILInjector InsertInPlaceAfterBranch(params CodeInstruction[] instructions)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			List<Label> labels = Instruction.labels;
			Instruction = new CodeInstruction(Instruction);
			Instruction.labels.Clear();
			this.instructions.InsertRange(index, instructions);
			Instruction.labels.AddRange(labels);
			if (matchEnd >= index)
			{
				matchEnd += instructions.Length;
			}
			return this;
		}

		public ILInjector InsertAfterBranch(params CodeInstruction[] instructions)
		{
			InsertInPlaceAfterBranch(instructions);
			index += instructions.Length;
			return this;
		}

		public ILInjector RemoveAllPreviousInstructions()
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			instructions.RemoveRange(0, index);
			matchEnd -= index;
			if (matchEnd < 0)
			{
				matchEnd = 0;
			}
			index = 0;
			return this;
		}

		public ILInjector Remove(int count = 1)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			instructions.RemoveRange(index, count);
			if (matchEnd > index)
			{
				matchEnd = Math.Max(index, matchEnd - count);
			}
			return this;
		}

		public ILInjector RemoveLastMatch()
		{
			GetLastMatchRange(out var start, out var size);
			List<Label> labels = instructions[start].labels;
			instructions.RemoveRange(start, size);
			index = start;
			matchEnd = start;
			instructions[start].labels.AddRange(labels);
			return this;
		}

		public ILInjector ReplaceLastMatch(params CodeInstruction[] replacementInstructions)
		{
			if (replacementInstructions.Length == 0)
			{
				throw new ArgumentException("Cannot replace a match with an empty array.");
			}
			GetLastMatchRange(out var start, out var size);
			List<Label> labels = instructions[start].labels;
			instructions.RemoveRange(start, size);
			instructions.InsertRange(start, replacementInstructions);
			index = start;
			matchEnd = start + replacementInstructions.Length;
			instructions[start].labels.AddRange(labels);
			return this;
		}

		public List<CodeInstruction> ReleaseInstructions()
		{
			List<CodeInstruction> result = instructions;
			instructions = null;
			return result;
		}

		public ILInjector PrintContext(int context, string header = "")
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid (" + header + ")");
			}
			StringBuilder stringBuilder = new StringBuilder(header);
			if (header.Length > 0)
			{
				stringBuilder.Append(':');
			}
			stringBuilder.AppendLine();
			GetLastMatchRangeAbsolute(out var start, out var end);
			int num = Math.Min(end + 1 + context, instructions.Count);
			for (int i = Math.Max(start - context, 0); i < num; i++)
			{
				if (end == -1 && i == index)
				{
					stringBuilder.Append("╶> ");
				}
				else
				{
					if (i >= start && i < end)
					{
						stringBuilder.Append("│");
					}
					else
					{
						stringBuilder.Append(" ");
					}
					if (i == index)
					{
						stringBuilder.Append("╶> ");
					}
					else
					{
						stringBuilder.Append("   ");
					}
				}
				stringBuilder.AppendLine($"{i}: {instructions[i]}");
			}
			MattyFixes.Log.LogFatal((object)stringBuilder);
			return this;
		}

		public ILInjector PrintContext(string header = "")
		{
			return PrintContext(4, header);
		}
	}
	internal interface ILMatcher
	{
		bool Matches(CodeInstruction instruction);

		ILMatcher CaptureAs(out CodeInstruction variable)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			variable = new CodeInstruction(OpCodes.Nop, (object)null);
			return new InstructionCapturingMatcher(this, variable);
		}

		unsafe ILMatcher CaptureOperandAs<T>(out T operand) where T : unmanaged
		{
			operand = default(T);
			fixed (T* operand2 = &operand)
			{
				return new OperandCapturingMatcher<T>(this, operand2);
			}
		}

		static ILMatcher Not(ILMatcher matcher)
		{
			return new NotMatcher(matcher);
		}

		static ILMatcher Opcode(OpCode opcode)
		{
			return new OpcodeMatcher(opcode);
		}

		static ILMatcher Opcodes(params OpCode[] opcodes)
		{
			return new OpcodesMatcher(opcodes);
		}

		static ILMatcher OpcodeOperand(OpCode opcode, object operand)
		{
			return new OpcodeOperandMatcher(opcode, operand);
		}

		static ILMatcher Instruction(CodeInstruction instruction)
		{
			return new InstructionMatcher(instruction);
		}

		static ILMatcher Ldarg(int? arg = null)
		{
			return new LdargMatcher(arg);
		}

		static ILMatcher Ldloc(int? loc = null)
		{
			return new LdlocMatcher(loc);
		}

		static ILMatcher Stloc(int? loc = null)
		{
			return new StlocMatcher(loc);
		}

		static ILMatcher Ldc(int? value = null)
		{
			return new LdcI32Matcher(value);
		}

		static ILMatcher Branch()
		{
			return new BranchMatcher();
		}

		static ILMatcher Ldfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (field == null)
			{
				MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Ldfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return new OpcodeOperandMatcher(OpCodes.Ldfld, field);
		}

		static ILMatcher Ldsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (field == null)
			{
				MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Ldsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return new OpcodeOperandMatcher(OpCodes.Ldsfld, field);
		}

		static ILMatcher Stfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (field == null)
			{
				MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Stfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return new OpcodeOperandMatcher(OpCodes.Stfld, field);
		}

		static ILMatcher Stsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (field == null)
			{
				MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Stsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return new OpcodeOperandMatcher(OpCodes.Stsfld, field);
		}

		static ILMatcher Callvirt(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (method == null)
			{
				MattyFixes.Log.LogWarning((object)$"Method passed to ILMatcher.Callvirt() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return OpcodeOperand(OpCodes.Callvirt, method);
		}

		static ILMatcher Call(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
		{
			if (method == null)
			{
				MattyFixes.Log.LogWarning((object)$"Method passed to ILMatcher.Call() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})");
			}
			return OpcodeOperand(OpCodes.Call, method);
		}

		static ILMatcher Predicate(Func<CodeInstruction, bool> predicate)
		{
			return new PredicateMatcher(predicate);
		}

		static ILMatcher Predicate(Func<FieldInfo, bool> predicate)
		{
			return new PredicateMatcher((CodeInstruction insn) => insn.operand is FieldInfo arg && predicate(arg));
		}
	}
	internal class NotMatcher : ILMatcher
	{
		private readonly ILMatcher matcher;

		public NotMatcher(ILMatcher matcher)
		{
			this.matcher = matcher;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return !matcher.Matches(instruction);
		}
	}
	internal class OpcodeMatcher : ILMatcher
	{
		private readonly OpCode opcode;

		public OpcodeMatcher(OpCode opcode)
		{
			this.opcode = opcode;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return instruction.opcode == opcode;
		}
	}
	internal class OpcodesMatcher : ILMatcher
	{
		private readonly OpCode[] opcodes;

		public OpcodesMatcher(OpCode[] opcodes)
		{
			this.opcodes = opcodes;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return opcodes.Contains(instruction.opcode);
		}
	}
	internal class OpcodeOperandMatcher : ILMatcher
	{
		private readonly OpCode opcode;

		private readonly object operand;

		public OpcodeOperandMatcher(OpCode opcode, object operand)
		{
			this.opcode = opcode;
			this.operand = operand;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (instruction.opcode == opcode)
			{
				return instruction.operand == operand;
			}
			return false;
		}
	}
	internal class InstructionMatcher : ILMatcher
	{
		private readonly OpCode opcode = instruction.opcode;

		private readonly object operand = instruction.operand;

		private readonly Label[] labels = instruction.labels.ToArray();

		public InstructionMatcher(CodeInstruction instruction)
		{
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (instruction.opcode != opcode)
			{
				return false;
			}
			if (instruction.operand != operand)
			{
				return false;
			}
			if (instruction.labels.Count != labels.Length)
			{
				return false;
			}
			for (int i = 0; i < labels.Length; i++)
			{
				if (labels[i] != instruction.labels[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	internal class LdargMatcher : ILMatcher
	{
		private readonly int? arg;

		public LdargMatcher(int? arg)
		{
			this.arg = arg;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!arg.HasValue)
			{
				return instruction.GetLdargIndex().HasValue;
			}
			return instruction.GetLdargIndex() == arg;
		}
	}
	internal class LdlocMatcher : ILMatcher
	{
		private readonly int? loc;

		public LdlocMatcher(int? loc)
		{
			this.loc = loc;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!loc.HasValue)
			{
				return instruction.GetLdlocIndex().HasValue;
			}
			return instruction.GetLdlocIndex() == loc;
		}
	}
	internal class StlocMatcher : ILMatcher
	{
		private readonly int? loc;

		public StlocMatcher(int? loc)
		{
			this.loc = loc;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!loc.HasValue)
			{
				return instruction.GetStlocIndex().HasValue;
			}
			return instruction.GetStlocIndex() == loc;
		}
	}
	internal class LdcI32Matcher : ILMatcher
	{
		private readonly int? value;

		public LdcI32Matcher(int? value)
		{
			this.value = value;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!value.HasValue)
			{
				return instruction.GetLdcI32().HasValue;
			}
			return instruction.GetLdcI32() == value;
		}
	}
	internal class BranchMatcher : ILMatcher
	{
		public bool Matches(CodeInstruction instruction)
		{
			Label? label = default(Label?);
			return CodeInstructionExtensions.Branches(instruction, ref label);
		}
	}
	internal class PredicateMatcher : ILMatcher
	{
		private readonly Func<CodeInstruction, bool> predicate;

		public PredicateMatcher(Func<CodeInstruction, bool> predicate)
		{
			this.predicate = predicate;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return predicate(instruction);
		}
	}
	internal class InstructionCapturingMatcher : ILMatcher
	{
		private readonly ILMatcher matcher;

		private readonly CodeInstruction variable;

		public InstructionCapturingMatcher(ILMatcher matcher, CodeInstruction variable)
		{
			this.matcher = matcher;
			this.variable = variable;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			bool flag = matcher.Matches(instruction);
			if (flag)
			{
				variable.opcode = instruction.opcode;
				variable.operand = instruction.operand;
				variable.blocks = instruction.blocks.ToList();
				variable.labels = instruction.labels.ToList();
			}
			return flag;
		}
	}
	internal class OperandCapturingMatcher<T> : ILMatcher where T : unmanaged
	{
		private readonly ILMatcher matcher;

		private unsafe readonly T* operand;

		public unsafe OperandCapturingMatcher(ILMatcher matcher, T* operand)
		{
			this.matcher = matcher;
			this.operand = operand;
			base..ctor();
		}

		public unsafe bool Matches(CodeInstruction instruction)
		{
			bool flag = matcher.Matches(instruction);
			if (flag)
			{
				*operand = (T)instruction.operand;
			}
			return flag;
		}
	}
	internal static class InstructionUtilities
	{
		public static CodeInstruction MakeLdarg(int index)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (index < 256)
			{
				return (CodeInstruction)(index switch
				{
					0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 
					1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 
					2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 
					3 => (object)new CodeInstruction(OpCodes.Ldarg_3, (object)null), 
					_ => (object)new CodeInstruction(OpCodes.Ldarg_S, (object)index), 
				});
			}
			return new CodeInstruction(OpCodes.Ldarg, (object)index);
		}

		public static int PopCount(this CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj)
			{
				MethodBase methodBase = (MethodBase)instruction.operand;
				int num = methodBase.GetParameters().Length;
				if (!methodBase.IsStatic)
				{
					num++;
				}
				return num;
			}
			if (instruction.opcode == OpCodes.Ret)
			{
				return 1;
			}
			return instruction.opcode.StackBehaviourPop switch
			{
				StackBehaviour.Pop0 => 0, 
				StackBehaviour.Pop1 => 1, 
				StackBehaviour.Pop1_pop1 => 2, 
				StackBehaviour.Popi => 1, 
				StackBehaviour.Popi_pop1 => 2, 
				StackBehaviour.Popi_popi => 2, 
				StackBehaviour.Popi_popi8 => 2, 
				StackBehaviour.Popi_popi_popi => 3, 
				StackBehaviour.Popi_popr4 => 2, 
				StackBehaviour.Popi_popr8 => 2, 
				StackBehaviour.Popref => 1, 
				StackBehaviour.Popref_pop1 => 2, 
				StackBehaviour.Popref_popi => 2, 
				StackBehaviour.Popref_popi_popi => 3, 
				StackBehaviour.Popref_popi_popi8 => 3, 
				StackBehaviour.Popref_popi_popr4 => 3, 
				StackBehaviour.Popref_popi_popr8 => 3, 
				StackBehaviour.Popref_popi_popref => 3, 
				StackBehaviour.Varpop => throw new NotImplementedException($"Variable pop on non-call instruction '{instruction}'"), 
				StackBehaviour.Popref_popi_pop1 => 3, 
				_ => throw new NotSupportedException($"StackBehaviourPop of {instruction.opcode.StackBehaviourPop} was not a pop for instruction '{instruction}'"), 
			};
		}

		public static int PushCount(this CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj)
			{
				if (instruction.operand is MethodInfo methodInfo && methodInfo.ReturnType == typeof(void))
				{
					return 0;
				}
				return 1;
			}
			return instruction.opcode.StackBehaviourPush switch
			{
				StackBehaviour.Push0 => 0, 
				StackBehaviour.Push1 => 1, 
				StackBehaviour.Push1_push1 => 2, 
				StackBehaviour.Pushi => 1, 
				StackBehaviour.Pushi8 => 1, 
				StackBehaviour.Pushr4 => 1, 
				StackBehaviour.Pushr8 => 1, 
				StackBehaviour.Pushref => 1, 
				StackBehaviour.Varpush => throw new NotImplementedException($"Variable push on non-call instruction '{instruction}'"), 
				_ => throw new NotSupportedException($"StackBehaviourPush of {instruction.opcode.StackBehaviourPush} was not a push for instruction '{instruction}'"), 
			};
		}

		public static int? GetLdargIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldarg_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldarg_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldarg_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldarg_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldarg || opcode == OpCodes.Ldarg_S)
			{
				return instruction.operand as int?;
			}
			return null;
		}

		public static int? GetLdlocIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldloc_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldloc_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldloc_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldloc_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S)
			{
				return (instruction.operand as LocalBuilder)?.LocalIndex;
			}
			return null;
		}

		public static int? GetStlocIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Stloc_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Stloc_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Stloc_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Stloc_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S)
			{
				return (instruction.operand as LocalBuilder)?.LocalIndex;
			}
			return null;
		}

		public static CodeInstruction LdlocToStloc(this CodeInstruction instruction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldloc_0)
			{
				return new CodeInstruction(OpCodes.Stloc_0, (object)null);
			}
			if (opcode == OpCodes.Ldloc_1)
			{
				return new CodeInstruction(OpCodes.Stloc_1, (object)null);
			}
			if (opcode == OpCodes.Ldloc_2)
			{
				return new CodeInstruction(OpCodes.Stloc_2, (object)null);
			}
			if (opcode == OpCodes.Ldloc_3)
			{
				return new CodeInstruction(OpCodes.Stloc_3, (object)null);
			}
			if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S)
			{
				return new CodeInstruction(OpCodes.Stloc, instruction.operand);
			}
			return null;
		}

		public static CodeInstruction StlocToLdloc(this CodeInstruction instruction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Stloc_0)
			{
				return new CodeInstruction(OpCodes.Ldloc_0, (object)null);
			}
			if (opcode == OpCodes.Stloc_1)
			{
				return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
			}
			if (opcode == OpCodes.Stloc_2)
			{
				return new CodeInstruction(OpCodes.Ldloc_2, (object)null);
			}
			if (opcode == OpCodes.Stloc_3)
			{
				return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
			}
			if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S)
			{
				return new CodeInstruction(OpCodes.Ldloc, instruction.operand);
			}
			return null;
		}

		public static int? GetLdcI32(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldc_I4_M1)
			{
				return -1;
			}
			if (opcode == OpCodes.Ldc_I4_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldc_I4_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldc_I4_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldc_I4_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldc_I4_4)
			{
				return 4;
			}
			if (opcode == OpCodes.Ldc_I4_5)
			{
				return 5;
			}
			if (opcode == OpCodes.Ldc_I4_6)
			{
				return 6;
			}
			if (opcode == OpCodes.Ldc_I4_7)
			{
				return 7;
			}
			if (opcode == OpCodes.Ldc_I4_8)
			{
				return 8;
			}
			if (opcode == OpCodes.Ldc_I4_S)
			{
				return instruction.operand as sbyte?;
			}
			if (opcode == OpCodes.Ldc_I4)
			{
				return instruction.operand as int?;
			}
			return null;
		}
	}
	public static class ReflectionExtensions
	{
		public static MethodInfo GetGenericMethod(this Type type, string name, Type[] parameters, Type[] genericArgs)
		{
			MethodInfo[] methods = type.GetMethods();
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				if (!(methodInfo.Name != name) && methodInfo.IsGenericMethodDefinition)
				{
					return methodInfo.MakeGenericMethod(genericArgs);
				}
			}
			return null;
		}
	}
}
namespace MattyFixes.Patches
{
	[HarmonyPatch]
	internal class CupBoardFix
	{
		internal struct ClosetHolder
		{
			public readonly UnlockableItem Unlockable;

			public readonly GameObject gameObject;

			public readonly List<ShelfHolder> Shelves;

			public readonly Collider Collider;

			public bool IsInitialized;

			public ClosetHolder()
			{
				IsInitialized = false;
				Unlockable = StartOfRound.Instance.unlockablesList.unlockables.Find((UnlockableItem u) => u.unlockableName == "Cupboard");
				gameObject = GameObject.Find("/Environment/HangarShip/StorageCloset");
				Collider = gameObject.GetComponent<Collider>();
				Shelves = gameObject.GetComponentsInChildren<PlaceableObjectsSurface>().Select(delegate(PlaceableObjectsSurface s)
				{
					ShelfHolder result = default(ShelfHolder);
					result.Shelf = s;
					result.Collider = ((Component)s).GetComponent<Collider>();
					return result;
				}).ToList();
			}
		}

		internal struct ShelfHolder
		{
			public PlaceableObjectsSurface Shelf;

			public Collider Collider;
		}

		private static ClosetHolder? _closet;

		internal static ClosetHolder Closet
		{
			get
			{
				ClosetHolder valueOrDefault = _closet.GetValueOrDefault();
				if (!_closet.HasValue)
				{
					valueOrDefault = new ClosetHolder();
					_closet = valueOrDefault;
				}
				return _closet.Value;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")]
		[HarmonyPatch(typeof(StartOfRound), "OnDestroy")]
		private static void ResetOnDisconnect()
		{
			_closet = null;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")]
		private static void AfterCupboardSync(StartOfRound __instance)
		{
			if (!((NetworkBehaviour)(object)__instance).IsRPCClientStage() || ((NetworkBehaviour)__instance).IsServer)
			{
				return;
			}
			ClosetHolder closet = Closet;
			if (closet.IsInitialized)
			{
				MattyFixes.VerboseCupboardLog((LogLevel)4, () => "SyncShipUnlockablesClientRpc Cupboard Triggered but was already Initialized!");
				return;
			}
			closet.IsInitialized = true;
			if (closet.Unlockable.inStorage)
			{
				return;
			}
			closet.gameObject.GetComponent<AutoParentToShip>().MoveToOffset();
			Physics.SyncTransforms();
			GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject item in source.Where((GrabbableObject g) => g.isInShipRoom))
			{
				float offset = 0f;
				if (item.hasHitGround)
				{
					offset = item.itemProperties.verticalOffset;
				}
				ShelfCheck(item, offset);
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(StartOfRound), "LoadShipGrabbableItems")]
		private static void OnServerSpawn(GrabbableObject __instance)
		{
			ClosetHolder closet = Closet;
			if (closet.IsInitialized)
			{
				MattyFixes.VerboseCupboardLog((LogLevel)4, () => "LoadShipGrabbableItems Cupboard Triggered but was already Initialized!");
				return;
			}
			closet.IsInitialized = true;
			if (closet.Unlockable.inStorage)
			{
				return;
			}
			closet.gameObject.GetComponent<AutoParentToShip>().MoveToOffset();
			Physics.SyncTransforms();
			GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject item in source.Where((GrabbableObject g) => g.isInShipRoom))
			{
				ShelfCheck(item);
			}
		}

		private static void ShelfCheck(GrabbableObject grabbable, float offset = 0f)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			MattyFixes.VerboseCupboardLog((LogLevel)16, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Cupboard Triggered!");
			if (grabbable is ClipboardItem || (grabbable is PhysicsProp && grabbable.itemProperties.itemName == "Sticky note"))
			{
				return;
			}
			float value = MattyFixes.PluginConfig.CupBoard.Tolerance.Value;
			float num = value * value;
			try
			{
				Vector3 pos = ((Component)grabbable).transform.position + Vector3.down * offset;
				MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Item pos {pos}!");
				ClosetHolder closet = Closet;
				float distance = float.MaxValue;
				PlaceableObjectsSurface val = null;
				Vector3? closest = null;
				MattyFixes.VerboseCupboardLog((LogLevel)32, delegate
				{
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_003f: 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)
					string itemName = grabbable.itemProperties.itemName;
					object arg2 = ((NetworkBehaviour)grabbable).NetworkObjectId;
					Bounds bounds2 = closet.Collider.bounds;
					return $"{itemName}({arg2}) - Cupboard pos {((Bounds)(ref bounds2)).min}!";
				});
				Collider collider = closet.Collider;
				float y = pos.y;
				Bounds bounds = collider.bounds;
				if (y < ((Bounds)(ref bounds)).max.y)
				{
					bounds = collider.bounds;
					if (((Bounds)(ref bounds)).SqrDistance(pos) <= num)
					{
						foreach (ShelfHolder shelf in closet.Shelves)
						{
							Vector3 val2 = shelf.Collider.ClosestPointOnBounds(pos);
							float tmp = pos.y - val2.y;
							MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Shelve is {tmp} away!");
							if (tmp >= 0f && tmp < distance)
							{
								val = shelf.Shelf;
								distance = tmp;
								closest = val2;
							}
						}
						MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Chosen Shelve is {distance} away!");
						MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - With hitpoint at {closest}!");
					}
				}
				Transform transform = ((Component)grabbable).transform;
				if ((Object)(object)val != (Object)null)
				{
					Vector3 newPos = closest.Value + Vector3.up * grabbable.itemProperties.verticalOffset;
					transform.parent = closet.gameObject.transform;
					transform.position = newPos;
					grabbable.targetFloorPosition = transform.localPosition;
					MattyFixes.VerboseCupboardLog((LogLevel)16, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Pos on shelf {newPos}!");
				}
			}
			catch (Exception arg)
			{
				MattyFixes.Log.LogError((object)$"Exception while checking for Cupboard {arg}");
			}
		}
	}
	[HarmonyPatch]
	internal class GrabbableStartPatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_0
		{
			public Animator[] animators;

			internal bool <ProcessGrabbable>b__0()
			{
				return animators.All(delegate(Animator a)
				{
					//IL_001c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					if (Object.op_Implicit((Object)(object)a) && !Mathf.Approximately(a.speed, 0f))
					{
						AnimatorStateInfo currentAnimatorStateInfo = a.GetCurrentAnimatorStateInfo(0);
						return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f;
					}
					return true;
				});
			}
		}

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

			private object <>2__current;

			public GrabbableObject grabbable;

			public bool updatePosition;

			private Item <itemType>5__2;

			private string <key>5__3;

			private float <oldOffset>5__4;

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

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

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

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

			private bool MoveNext()
			{
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Expected O, but got Unknown
				//IL_0153: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0();
					<itemType>5__2 = grabbable.itemProperties;
					<key>5__3 = <itemType>5__2.GetPath();
					<oldOffset>5__4 = <itemType>5__2.verticalOffset;
					CS$<>8__locals0.animators = ((Component)grabbable).GetComponentsInChildren<Animator>();
					<>2__current = (object)new WaitUntil((Func<bool>)(() => CS$<>8__locals0.animators.All(delegate(Animator a)
					{
						//IL_001c: Unknown result type (might be due to invalid IL or missing references)
						//IL_0021: Unknown result type (might be due to invalid IL or missing references)
						if (Object.op_Implicit((Object)(object)a) && !Mathf.Approximately(a.speed, 0f))
						{
							AnimatorStateInfo currentAnimatorStateInfo = a.GetCurrentAnimatorStateInfo(0);
							return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f;
						}
						return true;
					})));
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					if (!((IInjectedItem)<itemType>5__2).MattyFixes_HasComputedOffset)
					{
						((IInjectedItem)<itemType>5__2).MattyFixes_HasComputedOffset = true;
						MattyFixes.Log.LogDebug((object)$"{<key>5__3}({((NetworkBehaviour)grabbable).NetworkObjectId}) is computing vertical offset");
						<itemType>5__2.verticalOffset = ComputeVerticalOffset(grabbable);
						bool flag = Mathf.Approximately(<oldOffset>5__4, <itemType>5__2.verticalOffset);
						MattyFixes.Log.LogDebug((object)string.Format("{0} {1} offset is {2}", <key>5__3, flag ? "original" : "new", <itemType>5__2.verticalOffset));
						if (flag)
						{
							return false;
						}
					}
					if (!updatePosition)
					{
						return false;
					}
					Vector3 targetFloorPosition = grabbable.targetFloorPosition;
					GrabbableObject obj = grabbable;
					obj.targetFloorPosition -= Vector3.up * <oldOffset>5__4;
					GrabbableObject obj2 = grabbable;
					obj2.targetFloorPosition += Vector3.up * <itemType>5__2.verticalOffset;
					MattyFixes.Log.LogDebug((object)$"{<key>5__3}({((NetworkBehaviour)grabbable).NetworkObjectId}) position updated [{targetFloorPosition}] -> [{grabbable.targetFloorPosition}]");
					return false;
				}
				}
			}

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

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

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		internal static void OnObjectSpawn(GrabbableObject __instance)
		{
			if (MattyFixes.PluginConfig.ItemClipping.Enabled.Value)
			{
				Item itemProperties = __instance.itemProperties;
				if (!((IInjectedItem)itemProperties).MattyFixes_HasComputedOffset)
				{
					string path = itemProperties.GetPath();
					MattyFixes.Log.LogDebug((object)$"{path}({((NetworkBehaviour)__instance).NetworkObjectId}) needs to compute vertical offset - scheduled");
					bool updatePosition = ShouldSpawnOnGround(__instance) || (Object)(object)((Component)__instance).transform.parent == (Object)(object)CupBoardFix.Closet.gameObject.transform;
					((MonoBehaviour)__instance).StartCoroutine(ProcessGrabbable(__instance, updatePosition));
				}
			}
		}

		[IteratorStateMachine(typeof(<ProcessGrabbable>d__1))]
		private static IEnumerator ProcessGrabbable(GrabbableObject grabbable, bool updatePosition = true)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ProcessGrabbable>d__1(0)
			{
				grabbable = grabbable,
				updatePosition = updatePosition
			};
		}

		private static float ComputeVerticalOffset(GrabbableObject grabbable)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			Item itemProperties = grabbable.itemProperties;
			string path = itemProperties.GetPath();
			try
			{
				if (MattyFixes.PluginConfig.ItemClipping.ManualOffsetMap.TryGetValue(path, out var value))
				{
					return value;
				}
				ExecutionOptions val = new ExecutionOptions();
				((ExecutionOptions)(ref val)).VertexCache = VertexesExtensions.GlobalPartialCache;
				((ExecutionOptions)(ref val)).CullingMask = MattyFixes.VisibleLayerMask;
				((ExecutionOptions)(ref val)).LogHandler = MattyFixes.VerboseMeshLog;
				((ExecutionOptions)(ref val)).OverrideMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(grabbable.itemProperties.restingRotation.x, (float)grabbable.itemProperties.floorYOffset + 90f, grabbable.itemProperties.restingRotation.z), ((Component)grabbable).transform.lossyScale);
				ExecutionOptions val2 = val;
				Bounds val3 = default(Bounds);
				if (VertexesExtensions.TryGetBounds(((Component)grabbable).transform, ref val3, val2))
				{
					value = 0f - ((Bounds)(ref val3)).min.y;
					value += MattyFixes.PluginConfig.ItemClipping.VerticalOffset.Value;
				}
				else
				{
					value = itemProperties.verticalOffset;
				}
				return value;
			}
			catch (Exception arg)
			{
				MattyFixes.Log.LogError((object)$"{path} Failed to compute vertical offset! {arg}");
			}
			return itemProperties.verticalOffset;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		private static IEnumerable<CodeInstruction> RedirectSpawnOnGroundCheck(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
		{
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			FieldInfo field = typeof(GrabbableObject).GetField("itemProperties", AccessTools.all);
			FieldInfo field2 = typeof(Item).GetField("itemSpawnsOnGround", AccessTools.all);
			MethodInfo method = typeof(GrabbableStartPatch).GetMethod("NewSpawnOnGroundCheck", AccessTools.all);
			CodeInstruction variable;
			ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "RedirectSpawnOnGroundCheck", "./Plugin/src/Patches/GrabbableStartPatch.cs", 144), ILMatcher.Ldfld(field2, "RedirectSpawnOnGroundCheck", "./Plugin/src/Patches/GrabbableStartPatch.cs", 145), ILMatcher.Branch().CaptureAs(out variable));
			if (!iLInjector.IsValid)
			{
				MattyFixes.Log.LogWarning((object)"GrabbableObject.Start patch failed!!");
				MattyFixes.Log.LogDebug((object)string.Join("\n", iLInjector.ReleaseInstructions()));
				return list;
			}
			iLInjector.ReplaceLastMatch(InstructionUtilities.MakeLdarg(0), new CodeInstruction(OpCodes.Call, (object)method), variable);
			MattyFixes.Log.LogDebug((object)"GrabbableObject.Start patched!");
			return iLInjector.ReleaseInstructions();
		}

		private static bool NewSpawnOnGroundCheck(GrabbableObject grabbableObject)
		{
			MattyFixes.VerboseItemsLog((LogLevel)32, () => $"{grabbableObject.itemProperties.itemName}({((NetworkBehaviour)grabbableObject).NetworkObjectId}) processing GrabbableObject pos {((Component)grabbableObject).transform.position}");
			bool ret = ShouldSpawnOnGround(grabbableObject);
			MattyFixes.VerboseItemsLog((LogLevel)32, () => $"{grabbableObject.itemProperties.itemName}({((NetworkBehaviour)grabbableObject).NetworkObjectId}) processing GrabbableObject spawnState " + $"OnGround - was: {grabbableObject.itemProperties.itemSpawnsOnGround} new:{ret}");
			return ret;
		}

		private static bool ShouldSpawnOnGround(GrabbableObject grabbableObject)
		{
			bool result = grabbableObject.itemProperties.itemSpawnsOnGround;
			if (!MattyFixes.PluginConfig.OutOfBounds.Enabled.Value && !MattyFixes.PluginConfig.CupBoard.Enabled.Value)
			{
				return result;
			}
			if (grabbableObject is ClipboardItem || (grabbableObject is PhysicsProp && grabbableObject.itemProperties.itemName == "Sticky note"))
			{
				return result;
			}
			if (Object.op_Implicit((Object)(object)StartOfRound.Instance.localPlayerController) && !StartOfRoundPatch.IsInitializingGame)
			{
				return result;
			}
			if (MattyFixes.PluginConfig.OutOfBounds.Enabled.Value)
			{
				result = ((NetworkBehaviour)StartOfRound.Instance).IsServer;
			}
			if (!MattyFixes.PluginConfig.CupBoard.Enabled.Value)
			{
				return result;
			}
			if (Object.op_Implicit((Object)(object)CupBoardFix.Closet.gameObject) && (Object)(object)((Component)grabbableObject).transform.parent == (Object)(object)CupBoardFix.Closet.gameObject.transform)
			{
				result = false;
			}
			return result;
		}
	}
	[HarmonyPatch]
	internal static class ItemPatches
	{
		[HarmonyPatch(typeof(NetworkBehaviour), "OnNetworkSpawn")]
		internal static class NetworkSpawnPatch
		{
			[HarmonyPrefix]
			[HarmonyPriority(900)]
			private static void Prefix(NetworkBehaviour __instance)
			{
				GrabbableObject val = (GrabbableObject)(object)((__instance is GrabbableObject) ? __instance : null);
				if (val == null)
				{
					return;
				}
				Item itemProperties = val.itemProperties;
				TryUpdateItemRotation(itemProperties);
				if (!ComputedItems.Add(itemProperties) || !itemProperties.isConductiveMetal || !MattyFixes.PluginConfig.ReadableMeshes.Enabled.Value)
				{
					return;
				}
				try
				{
					if ((Object)(object)itemProperties.spawnPrefab != (Object)null)
					{
						CacheReadableMeshes(itemProperties.spawnPrefab);
					}
				}
				catch (Exception arg)
				{
					string path = itemProperties.GetPath();
					MattyFixes.Log.LogError((object)$"{path} Failed to mark prefab Mesh Readable! {arg}");
					BrokenMeshItems.Add(itemProperties);
					MattyFixes.Log.LogWarning((object)(path + " Added to the ignored Meshes!"));
				}
			}

			[HarmonyPostfix]
			[HarmonyPriority(-900)]
			private static void Postfix(NetworkBehaviour __instance)
			{
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				GrabbableObject val = (GrabbableObject)(object)((__instance is GrabbableObject) ? __instance : null);
				if (val == null || val is ClipboardItem || (val is PhysicsProp && val.itemProperties.itemName == "Sticky note") || (Object.op_Implicit((Object)(object)StartOfRound.Instance.localPlayerController) && !StartOfRoundPatch.IsInitializingGame))
				{
					return;
				}
				try
				{
					val.isInElevator = true;
					val.isInShipRoom = true;
					LungProp val2 = (LungProp)(object)((val is LungProp) ? val : null);
					if (val2 != null)
					{
						val2.isLungDocked = false;
						val2.isLungPowered = false;
						val2.isLungDockedInElevator = false;
						AudioSource component = ((Component)val2).GetComponent<AudioSource>();
						if (component != null)
						{
							component.Stop();
						}
					}
					if (MattyFixes.PluginConfig.ItemClipping.RotateOnSpawn.Value)
					{
						val.floorYRot = (int)Math.Floor(((Component)val).transform.eulerAngles.y - 90f - (float)val.itemProperties.floorYOffset);
						((Component)val).transform.rotation = Quaternion.Euler(val.itemProperties.restingRotation.x, ((Component)val).transform.eulerAngles.y, val.itemProperties.restingRotation.z);
					}
				}
				catch (Exception arg)
				{
					MattyFixes.Log.LogError((object)$"Exception while setting rotation of {val.itemProperties.GetPath()} :{arg}");
				}
			}
		}

		[HarmonyPatch]
		internal class StormyWeatherPatch
		{
			private static (ParentConstraint parent, ScaleConstraint scale) _staticElectricityConstraints;

			private static (Vector3 position, Vector3 rotation, Vector3 scale) _originalOffsets;

			[HarmonyPrefix]
			[HarmonyPatch(typeof(StormyWeather), "Start")]
			private static void Setup(StormyWeather __instance)
			{
				//IL_0015: 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)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				if (MattyFixes.PluginConfig.Particles.Lightning.Value != 0)
				{
					ParticleSystem staticElectricityParticle = __instance.staticElectricityParticle;
					ShapeModule shape = staticElectricityParticle.shape;
					_originalOffsets = (((ShapeModule)(ref shape)).position, ((ShapeModule)(ref shape)).rotation, ((ShapeModule)(ref shape)).scale);
					ParentConstraint val = ((Component)staticElectricityParticle).gameObject.AddComponent<ParentConstraint>();
					val.weight = 1f;
					val.translationAtRest = ((Component)staticElectricityParticle).transform.position;
					Quaternion rotation = ((Component)staticElectricityParticle).transform.rotation;
					val.rotationAtRest = ((Quaternion)(ref rotation)).eulerAngles;
					ScaleConstraint val2 = ((Component)val).gameObject.AddComponent<ScaleConstraint>();
					val2.weight = 1f;
					val2.scaleAtRest = ((Component)staticElectricityParticle).transform.lossyScale;
					_staticElectricityConstraints = (val, val2);
				}
			}

			[HarmonyTranspiler]
			[HarmonyPatch(typeof(StormyWeather), "SetStaticElectricityWarning")]
			private static IEnumerable<CodeInstruction> SetStaticElectricityWarning(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
			{
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Expected O, but got Unknown
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0180: Expected O, but got Unknown
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Expected O, but got Unknown
				List<CodeInstruction> list = instructions.ToList();
				FieldInfo field = typeof(StormyWeather).GetField("staticElectricityParticle", AccessTools.all);
				MethodInfo method = typeof(ParticleSystem).GetProperty("time", AccessTools.all)?.GetSetMethod();
				MethodInfo method2 = typeof(ParticleSystem).GetMethod("Play", 0, Array.Empty<Type>());
				MethodInfo method3 = typeof(StormyWeatherPatch).GetMethod("ChangeParticleShape", AccessTools.all);
				ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 354), ILMatcher.Ldarg(), ILMatcher.Callvirt(method, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 356), ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 358), ILMatcher.Callvirt(method2, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 359));
				if (!iLInjector.IsValid)
				{
					MattyFixes.Log.LogWarning((object)"StormyWeather.SetStaticElectricityWarning patch failed!!");
					MattyFixes.Log.LogDebug((object)string.Join("\n", iLInjector.ReleaseInstructions()));
					return list;
				}
				iLInjector.Insert(new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Call, (object)method3));
				MattyFixes.Log.LogDebug((object)"StormyWeather.SetStaticElectricityWarning patched!");
				return iLInjector.ReleaseInstructions();
			}

			private static void ChangeParticleShape(StormyWeather __instance, NetworkObject warningObject)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0245: Unknown result type (might be due to invalid IL or missing references)
				//IL_0251: Unknown result type (might be due to invalid IL or missing references)
				//IL_025d: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					GrabbableObject component = ((Component)warningObject).gameObject.GetComponent<GrabbableObject>();
					ParticleSystem staticElectricityParticle = __instance.staticElectricityParticle;
					ShapeModule shape = staticElectricityParticle.shape;
					MainModule main = staticElectricityParticle.main;
					ConstraintSource val2;
					switch (MattyFixes.PluginConfig.Particles.Lightning.Value)
					{
					case MattyFixes.PluginConfig.Particles.LightningType.Fixed:
					{
						val2 = default(ConstraintSource);
						((ConstraintSource)(ref val2)).sourceTransform = ((Component)warningObject).transform;
						((ConstraintSource)(ref val2)).weight = 1f;
						ConstraintSource val4 = val2;
						((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)2;
						_staticElectricityConstraints.parent.AddSource(val4);
						_staticElectricityConstraints.scale.AddSource(val4);
						_staticElectricityConstraints.parent.constraintActive = true;
						_staticElectricityConstraints.scale.constraintActive = true;
						((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
						((ShapeModule)(ref shape)).radiusThickness = 0.01f;
						ExecutionOptions val5 = new ExecutionOptions();
						((ExecutionOptions)(ref val5)).VertexCache = VertexesExtensions.GlobalPartialCache;
						((ExecutionOptions)(ref val5)).CullingMask = MattyFixes.VisibleLayerMask;
						((ExecutionOptions)(ref val5)).LogHandler = MattyFixes.VerboseMeshLog;
						ExecutionOptions val6 = val5;
						Vector3[] vertexes = VertexesExtensions.GetVertexes(((Component)warningObject).transform, val6);
						Bounds? bounds = VertexesExtensions.GetBounds((IEnumerable<Vector3>)vertexes);
						if (bounds.HasValue)
						{
							Bounds value = bounds.Value;
							float item = VertexesExtensions.GetFarthestPoint((IEnumerable<Vector3>)vertexes, ((Bounds)(ref value)).center).Item2;
							((ShapeModule)(ref shape)).radius = item;
							value = bounds.Value;
							((ShapeModule)(ref shape)).position = ((Bounds)(ref value)).center;
						}
						break;
					}
					case MattyFixes.PluginConfig.Particles.LightningType.Alternate:
						if (BrokenMeshItems.Contains(component.itemProperties))
						{
							break;
						}
						try
						{
							GameObject gameObject = ((Component)((ShapeModule)(ref shape)).meshRenderer).gameObject;
							MeshFilter val = default(MeshFilter);
							if (gameObject.TryGetComponent<MeshFilter>(ref val))
							{
								val2 = default(ConstraintSource);
								((ConstraintSource)(ref val2)).sourceTransform = gameObject.transform;
								((ConstraintSource)(ref val2)).weight = 1f;
								ConstraintSource val3 = val2;
								((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)2;
								_staticElectricityConstraints.parent.AddSource(val3);
								_staticElectricityConstraints.scale.AddSource(val3);
								_staticElectricityConstraints.parent.constraintActive = true;
								_staticElectricityConstraints.scale.constraintActive = true;
								Mesh readableMesh = GetReadableMesh(val.sharedMesh);
								((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)6;
								((ShapeModule)(ref shape)).mesh = readableMesh;
								((ShapeModule)(ref shape)).meshRenderer = null;
								((ShapeModule)(ref shape)).position = Vector3.zero;
								((ShapeModule)(ref shape)).rotation = Vector3.zero;
								((ShapeModule)(ref shape)).scale = Vector3.one;
							}
							break;
						}
						catch (Exception arg)
						{
							Item itemProperties = component.itemProperties;
							string path = itemProperties.GetPath();
							MattyFixes.Log.LogError((object)$"{path} Failed to make prefab Mesh Readable! {arg}");
							BrokenMeshItems.Add(itemProperties);
							MattyFixes.Log.LogWarning((object)(path + " Added to the ignored Meshes!"));
							break;
						}
					case MattyFixes.PluginConfig.Particles.LightningType.Vanilla:
						break;
					}
				}
				catch (Exception ex)
				{
					MattyFixes.Log.LogError((object)ex);
				}
			}

			[HarmonyPrefix]
			[HarmonyPatch(typeof(StormyWeather), "LightningStrike")]
			private static void ResetMeshes(StormyWeather __instance, bool useTargetedObject)
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				if (MattyFixes.PluginConfig.Particles.Lightning.Value != 0 && !((Object)(object)__instance.setStaticToObject == (Object)null) && useTargetedObject)
				{
					_staticElectricityConstraints.parent.constraintActive = false;
					_staticElectricityConstraints.scale.constraintActive = false;
					_staticElectricityConstraints.parent.SetSources(new List<ConstraintSource>());
					_staticElectricityConstraints.scale.SetSources(new List<ConstraintSource>());
					ShapeModule shape = __instance.staticElectricityParticle.shape;
					MainModule main = __instance.staticElectricityParticle.main;
					((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)1;
					((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)13;
					((ShapeModule)(ref shape)).position = _originalOffsets.position;
					((ShapeModule)(ref shape)).rotation = _originalOffsets.rotation;
					((ShapeModule)(ref shape)).scale = _originalOffsets.scale;
				}
			}
		}

		[HarmonyPatch]
		internal class RandomFlyParticlePatches
		{
			[HarmonyTranspiler]
			[HarmonyPatch(typeof(RandomFlyParticle), "InitializeAfterPositioning")]
			private static IEnumerable<CodeInstruction> InitializeAfterPositioning(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
			{
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Expected O, but got Unknown
				List<CodeInstruction> list = instructions.ToList();
				MethodInfo method = typeof(ShapeModule).GetProperty("meshRenderer", AccessTools.all)?.GetSetMethod();
				MethodInfo method2 = typeof(RandomFlyParticlePatches).GetMethod("ChangeParticleShape", AccessTools.all);
				ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Call(method, "InitializeAfterPositioning", "./Plugin/src/Patches/ItemPatches.cs", 536));
				if (!iLInjector.IsValid)
				{
					MattyFixes.Log.LogWarning((object)"RandomFlyParticle.InitializeAfterPositioning patch failed!!");
					MattyFixes.Log.LogDebug((object)string.Join("\n", iLI