Decompiled source of Enhanced Monsters v1.4.0

BepInEx/plugins/EnhancedMonsters/EnhancedMonsters.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EnhancedMonsters.Config;
using EnhancedMonsters.Monobehaviours;
using EnhancedMonsters.NetcodePatcher;
using EnhancedMonsters.Networking;
using EnhancedMonsters.Patches;
using EnhancedMonsters.Utils;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLib.Modules;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using MelanieMeliciousCooked;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyFileVersion("1.4.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnhancedMonsters
{
	[BepInPlugin("com.velddev.enhancedmonsters", "Enhanced Monsters", "1.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("Entity378.sellbodies")]
	public class Plugin : BaseUnityPlugin
	{
		private static readonly Harmony harmony = new Harmony("com.velddev.enhancedmonsters");

		[NotNull]
		public static ManualLogSource? logger;

		internal static Plugin Singleton
		{
			[return: NotNull]
			get;
			private set; }

		public static GameObject EnemyToPropPrefab { get; private set; }

		public static GameObject NetworkHandlerPrefab { get; private set; }

		private void Awake()
		{
			Singleton = this;
			logger = ((BaseUnityPlugin)this).Logger;
			new LocalConfig(((BaseUnityPlugin)this).Config);
			logger.LogInfo((object)"Local config initialized.");
			logger.LogInfo((object)"This is (maybe) NOT an RPG mod. And hi btw.");
			EnemiesDataManager.LoadEnemiesData();
			new SyncedConfig(((BaseUnityPlugin)this).Config);
			logger.LogInfo((object)"Enemies data loaded and ready to be synchronized.");
			ApplyAllPatches();
			logger.LogDebug((object)"All harmony patches have been applied (energistics).");
			CreateThePrefab();
			logger.LogDebug((object)"The Prefab have been created correctly");
			CreateNetworkHandlerPrefab();
			logger.LogDebug((object)"EnhancedMonstersNetworkHandler network prefab registered");
			if ((Object)(object)FastResourcesManager.EnemyScrapIcon == (Object)null)
			{
				logger.LogError((object)"EnemyScrapIcon didn't load yet. Caution advised.");
			}
			else
			{
				logger.LogInfo((object)"EnemyScrapIcon loaded correctly and is ready to use !");
			}
		}

		private static void ApplyAllPatches()
		{
			if (logger == null)
			{
				throw new NullReferenceException("logger is null. Cannot process further because it means that the mod was not initialized yet.");
			}
			logger.LogDebug((object)"Applying patches...");
			harmony.PatchAll(typeof(EnemyAI_Patches));
			harmony.PatchAll(typeof(MenuManager_Patches));
			harmony.PatchAll(typeof(PlayerControllerB_Patches));
			harmony.PatchAll(typeof(GameNetworkManager_Patches));
			harmony.PatchAll(typeof(StartOfRound_Patches));
			logger.LogDebug((object)"All Harmony patches applied.");
		}

		private static void CreateThePrefab()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NetworkPrefabs.CreateNetworkPrefab("EnemyAsProp");
			val.tag = "PhysicsProp";
			val.layer = 6;
			NetworkObject component = val.GetComponent<NetworkObject>();
			component.AutoObjectParentSync = false;
			component.DontDestroyWithOwner = true;
			BoxCollider val2 = val.AddComponent<BoxCollider>();
			((Collider)val2).enabled = true;
			((Collider)val2).isTrigger = true;
			val2.size = new Vector3(1.5f, 1.5f, 1.5f);
			val.AddComponent<EnemyScrap>();
			val.AddComponent<AudioSource>();
			val.AddComponent<OccludeAudio>();
			val.AddComponent<AudioLowPassFilter>();
			NetworkPrefabs.RegisterNetworkPrefab(val);
			EnemyToPropPrefab = val;
		}

		private static void CreateNetworkHandlerPrefab()
		{
			GameObject val = NetworkPrefabs.CreateNetworkPrefab("EnhancedMonstersNetworkHandler");
			NetworkObject component = val.GetComponent<NetworkObject>();
			component.AutoObjectParentSync = false;
			component.DontDestroyWithOwner = true;
			val.AddComponent<EnhancedMonstersNetworkHandler>();
			NetworkPrefabs.RegisterNetworkPrefab(val);
			NetworkHandlerPrefab = val;
		}
	}
	public static class PluginInfo
	{
		public const int ConfigVersion = 11;

		public const string Version = "1.4.0";

		public const string GUID = "com.velddev.enhancedmonsters";

		public const string DisplayName = "Enhanced Monsters";
	}
}
namespace EnhancedMonsters.Utils
{
	public static class EnemiesDataManager
	{
		[JsonObject]
		public class EnemyDataFile
		{
			public int Version { get; set; }

			public Dictionary<string, EnemyData> EnemiesData { get; set; }

			[JsonConstructor]
			public EnemyDataFile(int version, Dictionary<string, EnemyData> enemiesData)
			{
				Version = version;
				EnemiesData = enemiesData ?? new Dictionary<string, EnemyData>();
				base..ctor();
			}
		}

		public static readonly Dictionary<string, EnemyData> EnemiesData = new Dictionary<string, EnemyData>();

		public static readonly Dictionary<string, EnemyData> DefaultEnemiesData = new Dictionary<string, EnemyData>
		{
			["Manticoil"] = new EnemyData(pickupable: true, 10, 20, 12f, "F", new EnemyData.EnemyMetadata(new Vec3(-0.25f, 0.25f, 0.15f), new Vec3(180f, 0f, -90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)),
			["Tulip Snake"] = new EnemyData(pickupable: true, 20, 30, 7f, "F", new EnemyData.EnemyMetadata(new Vec3(-0.15f, 0.1f, 0.11f), new Vec3(0f, 90f, 90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)),
			["Hoarding bug"] = new EnemyData(pickupable: true, 55, 90, 50f, "E", new EnemyData.EnemyMetadata(new Vec3(0.1f, 0.2f, -0.3f), new Vec3(0f, 0f, 90f), new Vec3(0f, 0f, 0f))),
			["Puffer"] = new EnemyData(pickupable: true, 30, 60, 69f, "E", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))),
			["Centipede"] = new EnemyData(pickupable: true, 45, 70, 35f, "D", new EnemyData.EnemyMetadata(new Vec3(-0.25f, 0.1f, 0f), new Vec3(0f, 0f, -90f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)),
			["Baboon hawk"] = new EnemyData(pickupable: true, 75, 100, 105f, "D", new EnemyData.EnemyMetadata(new Vec3(-0.3f, 0.5f, 1.5f), new Vec3(0f, 0f, 90f), new Vec3(0f, 0f, 0f))),
			["Bunker Spider"] = new EnemyData(pickupable: true, 70, 110, 75f, "C", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))),
			["MouthDog"] = new EnemyData(pickupable: true, 175, 250, 250f, "C", new EnemyData.EnemyMetadata(new Vec3(-1.25f, -1f, -0.5f), new Vec3(180f, 0f, -90f), new Vec3(180f, 0f, 180f))),
			["Crawler"] = new EnemyData(pickupable: true, 120, 160, 100f, "B", new EnemyData.EnemyMetadata(new Vec3(-0.5f, 0f, -1f), new Vec3(0f, 0f, -60f), new Vec3(0f, 0f, 0f))),
			["Flowerman"] = new EnemyData(pickupable: true, 160, 190, 40f, "B", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 1.5f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)),
			["Butler"] = new EnemyData(pickupable: true, 170, 199, 77f, "B", new EnemyData.EnemyMetadata(new Vec3(-0.5f, 0f, 1f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)),
			["Nutcracker"] = new EnemyData(pickupable: true, 190, 220, 43f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 1.5f), new Vec3(0f, 90f, -90f), new Vec3(-90f, 0f, 0f), animateOnDeath: false)),
			["Maneater"] = new EnemyData(pickupable: true, 250, 290, 42f, "S", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), animateOnDeath: true, twoHanded: false)),
			["Docile Locust Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata()),
			["Red pill"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata()),
			["Blob"] = new EnemyData(pickupable: false, 0, 0, 0f, "D", new EnemyData.EnemyMetadata()),
			["Red Locust Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "C", new EnemyData.EnemyMetadata()),
			["Butler Bees"] = new EnemyData(pickupable: false, 0, 0, 0f, "C", new EnemyData.EnemyMetadata()),
			["Earth Leviathan"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()),
			["Masked"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()),
			["Clay Surgeon"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()),
			["Spring"] = new EnemyData(pickupable: false, 0, 0, 0f, "A", new EnemyData.EnemyMetadata()),
			["Jester"] = new EnemyData(pickupable: false, 0, 0, 0f, "S+", new EnemyData.EnemyMetadata()),
			["RadMech"] = new EnemyData(pickupable: false, 0, 0, 0f, "S+", new EnemyData.EnemyMetadata()),
			["Girl"] = new EnemyData(pickupable: false, 0, 0, 0f, "?", new EnemyData.EnemyMetadata()),
			["Lasso"] = new EnemyData(pickupable: false, 0, 0, 0f, "dont exist haha", new EnemyData.EnemyMetadata()),
			["ForestGiant"] = new EnemyData(pickupable: false, 0, 0, 0f, "S", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 90f, 0f), new Vec3(90f, 0f, 0f), animateOnDeath: false)),
			["PinkGiant"] = new EnemyData(pickupable: false, 0, 0, 0f, "F", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 90f, 0f), new Vec3(0f, 0f, 0f), animateOnDeath: false)),
			["Football"] = new EnemyData(pickupable: false, 0, 0, 0f, "B", new EnemyData.EnemyMetadata()),
			["Locker"] = new EnemyData(pickupable: false, 0, 0, 0f, "A", new EnemyData.EnemyMetadata()),
			["Bush Wolf"] = new EnemyData(pickupable: true, 250, 320, 51f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))),
			["PjonkGoose"] = new EnemyData(pickupable: true, 279, 340, 64f, "A", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f)))
		};

		public static string EnemiesDataFile = Path.Combine(Paths.ConfigPath, "EnhancedMonsters", "EnemiesData.json");

		public static readonly Dictionary<string, GameObject> Enemies2Props = new Dictionary<string, GameObject>();

		public static readonly List<Item> AllEnemiesScraps = new List<Item>();

		public static void LoadEnemiesData()
		{
			if (!File.Exists(EnemiesDataFile))
			{
				Plugin.logger.LogWarning((object)"Enemy Data File did not exist!");
				EnemiesData.ProperConcat(DefaultEnemiesData);
				SaveEnemiesData();
				return;
			}
			string text = File.ReadAllText(EnemiesDataFile);
			Plugin.logger.LogDebug((object)text);
			EnemyDataFile enemyDataFile = JsonConvert.DeserializeObject<EnemyDataFile>(text);
			if (enemyDataFile == null)
			{
				Plugin.logger.LogWarning((object)"Enemy Data File seems to be empty or invalid.");
				EnemiesData.ProperConcat(DefaultEnemiesData);
				SaveEnemiesData();
			}
			else if (checked(11 - enemyDataFile.Version) > 1)
			{
				Plugin.logger.LogWarning((object)"Enemy Data File seems to be outdated. A new config file will be created.");
				EnemiesData.ProperConcat(DefaultEnemiesData);
				string text2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "..", "config", "EnhancedMonsters", "OLD_EnemiesData.json");
				if (File.Exists(text2))
				{
					File.Delete(text2);
				}
				File.Move(EnemiesDataFile, text2);
				SaveEnemiesData();
			}
			else
			{
				EnemiesData.ProperConcat(enemyDataFile.EnemiesData);
				Plugin.logger.LogDebug((object)$"{enemyDataFile} => {EnemiesData.Count}");
				EnemiesData.ProperConcat(DefaultEnemiesData);
				Plugin.logger.LogDebug((object)$"{DefaultEnemiesData.Count} => {EnemiesData.Count}");
				SaveEnemiesData();
			}
		}

		public static void RegisterEnemy(string enemyName, bool sellable, int minPrice, int maxPrice, float mass, string rank, EnemyData.EnemyMetadata metadata, bool overrideRegister = false)
		{
			if (!EnemiesData.ContainsKey(enemyName))
			{
				EnemiesData.Add(enemyName, new EnemyData(sellable, minPrice, maxPrice, mass, rank, metadata));
			}
			else
			{
				if (!overrideRegister)
				{
					string name = Assembly.GetCallingAssembly().GetName().Name;
					Plugin.logger.LogWarning((object)("Cannot register modded from mod " + name + " enemy " + enemyName + ": It is already registered (either from file or from ."));
					return;
				}
				EnemiesData[enemyName] = new EnemyData(sellable, minPrice, maxPrice, mass, rank, metadata);
			}
			if (SyncedConfig.Instance == null || SyncedConfig.IsHost || !NetworkManager.Singleton.IsListening)
			{
				SyncedConfig.BroadcastSync();
			}
		}

		internal static void RegisterEnemy(string enemyName, EnemyData enemyData)
		{
			if (SyncedConfig.IsHost || !NetworkManager.Singleton.IsListening)
			{
				if (EnemiesData != SyncedConfig.Instance.EnemiesData)
				{
					Plugin.logger.LogError((object)"Cannot update the mob configs. Somehow, the EnemiesData from the EnemiesDataManager and the one from the SyncedConfigs are not the same, even though they both are yours.");
				}
				else if (!EnemiesData.TryAdd(enemyName, enemyData))
				{
					Plugin.logger.LogDebug((object)("EnemyData '" + enemyName + "' already exists!"));
				}
				else
				{
					SyncedConfig.BroadcastSync();
				}
			}
		}

		public static void SaveEnemiesData()
		{
			if (!SyncedConfig.IsHost)
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if (singleton != null && singleton.IsListening)
				{
					return;
				}
			}
			EnemyDataFile enemyDataFile = new EnemyDataFile(11, EnemiesData);
			string contents = JsonConvert.SerializeObject((object)enemyDataFile, (Formatting)1);
			if (!Directory.Exists(Path.GetDirectoryName(EnemiesDataFile)))
			{
				Directory.CreateDirectory(Path.GetDirectoryName(EnemiesDataFile));
			}
			File.WriteAllText(EnemiesDataFile, contents);
			Plugin.logger.LogInfo((object)"Saved enemies data.");
		}

		public static void ScanAndRegisterUnknownEnemies()
		{
			EnemyAI[] array = Resources.FindObjectsOfTypeAll<EnemyAI>();
			Plugin.logger.LogInfo((object)$"Scanning {array.Length} enemies for unknown entries");
			EnemyAI[] array2 = array;
			foreach (EnemyAI val in array2)
			{
				if (val == null)
				{
					Plugin.logger.LogWarning((object)"An enemy is null!");
				}
				else if (val.enemyType == null)
				{
					Plugin.logger.LogWarning((object)(((Object)val).name + " has a null enemyType (tf?)"));
				}
				else if (!SyncedConfig.Instance.EnemiesData.ContainsKey(val.enemyType.enemyName))
				{
					RegisterEnemy(val.enemyType.enemyName, new EnemyData(pickupable: true, 80, 250, 50f, "E", new EnemyData.EnemyMetadata(new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f), new Vec3(0f, 0f, 0f))));
					Plugin.logger.LogInfo((object)("Mob was not registered. Registered it with name '" + val.enemyType.enemyName + "'"));
				}
			}
			SaveEnemiesData();
		}

		public static void EnsureEnemy2PropPrefabs()
		{
			EnemyAI[] array = Resources.FindObjectsOfTypeAll<EnemyAI>();
			EnemyAI[] array2 = array;
			foreach (EnemyAI val in array2)
			{
				if ((Object)(object)val.enemyType == (Object)null)
				{
					Plugin.logger.LogWarning((object)("Entity " + ((Object)val).name + " have been skipped: This entity lacks an EnemyType !"));
					continue;
				}
				string enemyName = val.enemyType.enemyName;
				Plugin.logger.LogInfo((object)("Ensuring NetworkPrefab '" + enemyName + "'"));
				if (!TryUpdateExistingPrefab(val, enemyName) && SyncedConfig.Instance.EnemiesData.TryGetValue(enemyName, out var value) && value.Pickupable)
				{
					GameObject visual = BuildVisualCopy(val);
					GameObject val2 = BuildScrapPrefab(val, enemyName, visual, value);
					if (!((Object)(object)val2 == (Object)null))
					{
						ScanNodeProperties componentInChildren = val2.GetComponentInChildren<ScanNodeProperties>();
						Item enemyItem = BuildItemScriptable(enemyName, value, val2, componentInChildren);
						RegisterPrefabAndItem(enemyName, val2, enemyItem);
					}
				}
			}
			if (FarmingAndCookingSupport.FarmingAndCookingLoaded)
			{
				FarmingAndCookingSupport.RegisterFarmingAndCookingBodies(AllEnemiesScraps);
			}
		}

		private static bool TryUpdateExistingPrefab(EnemyAI enemy, string enemyName)
		{
			if (!Enemies2Props.TryGetValue(enemyName, out GameObject value))
			{
				return false;
			}
			EnemyData enemyData = SyncedConfig.Instance.EnemiesData[enemyName];
			if (!enemyData.Pickupable)
			{
				Enemies2Props.Remove(enemyName);
				return true;
			}
			EnemyScrap component = value.GetComponent<EnemyScrap>();
			component.enemyType = enemy.enemyType;
			((GrabbableObject)component).itemProperties.minValue = enemyData.MinValue;
			((GrabbableObject)component).itemProperties.maxValue = enemyData.MaxValue;
			((GrabbableObject)component).itemProperties.weight = enemyData.LCMass;
			return true;
		}

		private static GameObject BuildVisualCopy(EnemyAI enemy)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(((Object)enemy).name + " neutralized");
			foreach (Transform item in ((Component)enemy).transform)
			{
				Transform val2 = item;
				if (!((Object)val2).name.StartsWith("MapDot") && !((Object)val2).name.StartsWith("Collider") && !((Object)val2).name.StartsWith("VoiceSFX") && !((Object)val2).name.StartsWith("CreatureSFX") && !((Object)val2).name.StartsWith("SeepingSFX") && !((Object)val2).name.StartsWith("CreatureVoice") && !((Object)val2).name.StartsWith("Ambience"))
				{
					Transform val3 = Object.Instantiate<Transform>(val2);
					((Object)val3).name = ((Object)val2).name;
					((Component)val3).transform.parent = val.transform;
				}
			}
			val.RemoveComponentsInChildren<Collider>();
			val.RemoveComponentsInChildren<AudioLowPassFilter>();
			val.RemoveComponentsInChildren<AudioReverbFilter>();
			val.RemoveComponentsInChildren<OccludeAudio>();
			val.RemoveComponentsInChildren<EnemyAICollisionDetect>();
			val.RemoveComponentsInChildren<AudioSource>();
			val.RemoveComponentsInChildren<ParticleSystem>();
			val.RemoveComponentsInChildren<ParticleSystemRenderer>();
			val.transform.localScale = ((Component)enemy).transform.localScale;
			return val;
		}

		private static GameObject BuildScrapPrefab(EnemyAI enemy, string enemyName, GameObject visual, EnemyData enemyData)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NetworkPrefabs.CloneNetworkPrefab(Plugin.EnemyToPropPrefab, "Dead " + enemyName);
			visual.transform.parent = val.transform;
			Plugin.logger.LogInfo((object)("Attached " + ((Object)visual).name + " to " + ((Object)visual.transform.parent).name));
			EnemyScrap component = val.GetComponent<EnemyScrap>();
			component.EnemyGameObject = visual;
			CleanEnemyObj(component.EnemyGameObject);
			((GrabbableObject)component).grabbable = true;
			((GrabbableObject)component).grabbableToEnemies = false;
			component.enemyType = enemy.enemyType;
			BoxCollider component2 = val.GetComponent<BoxCollider>();
			component2.size = enemyData.Metadata.CollisionExtents;
			if (enemyName == "Bunker Spider")
			{
				val.AddComponent<SpiderArachnophobiaToggle>();
			}
			ScanNodeProperties componentInChildren = visual.GetComponentInChildren<ScanNodeProperties>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				Plugin.logger.LogWarning((object)("Enemy '" + enemyName + "' has no ScanNodeProperties; corpse cannot be networked-scanned. Discarding scrap prefab."));
				Object.Destroy((Object)(object)val);
				return null;
			}
			Transform transform = ((Component)componentInChildren).gameObject.transform;
			((Component)transform).transform.parent = val.transform;
			((Component)transform).gameObject.AddComponent<BoxCollider>();
			transform.localPosition = new Vector3(0f, 0f, 0f);
			componentInChildren.maxRange = 13;
			componentInChildren.minRange = 1;
			componentInChildren.nodeType = 2;
			componentInChildren.requiresLineOfSight = true;
			componentInChildren.headerText = "Dead " + componentInChildren.headerText;
			return val;
		}

		private static Item BuildItemScriptable(string enemyName, EnemyData enemyData, GameObject scrapPrefab, ScanNodeProperties scanNodeProperties)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Item val = ScriptableObject.CreateInstance<Item>();
			EnemyScrap component = scrapPrefab.GetComponent<EnemyScrap>();
			((GrabbableObject)component).itemProperties = val;
			((Object)val).name = enemyName + " scrap";
			val.itemName = scanNodeProperties.headerText;
			val.saveItemVariable = true;
			val.itemIcon = FastResourcesManager.EnemyScrapIcon;
			val.minValue = enemyData.MinValue;
			val.maxValue = enemyData.MaxValue;
			val.allowDroppingAheadOfPlayer = true;
			val.canBeGrabbedBeforeGameStart = true;
			val.isScrap = true;
			val.itemSpawnsOnGround = false;
			val.twoHanded = enemyData.Metadata.TwoHanded;
			val.requiresBattery = false;
			val.twoHandedAnimation = enemyData.Metadata.TwoHanded;
			val.weight = enemyData.LCMass;
			val.spawnPrefab = scrapPrefab;
			val.restingRotation = enemyData.Metadata.FloorRotation;
			val.rotationOffset = enemyData.Metadata.HandRotation;
			val.positionOffset = enemyData.Metadata.MeshOffset;
			EnemyData enemyData2 = SyncedConfig.Default.EnemiesData[enemyName];
			val.dropSFX = ResolveSfx(enemyData2.Metadata.DropSFX);
			val.grabSFX = ResolveSfx(enemyData2.Metadata.GrabSFX);
			val.pocketSFX = ResolveSfx(enemyData2.Metadata.PocketSFX);
			return val;
		}

		private static AudioClip ResolveSfx(string sfxKey)
		{
			if (string.IsNullOrEmpty(sfxKey) || sfxKey == "none")
			{
				return null;
			}
			if (sfxKey == "default")
			{
				return FastResourcesManager.EnemyDropDefaultSound;
			}
			if (FastResourcesManager.CustomAudioClips.TryGetValue(sfxKey, out AudioClip value))
			{
				return value;
			}
			Plugin.logger.LogWarning((object)("Custom SFX '" + sfxKey + "' not found in CustomAudioClips. Using default. (File missing or coroutine still running?)"));
			return FastResourcesManager.EnemyDropDefaultSound;
		}

		private static void RegisterPrefabAndItem(string enemyName, GameObject scrapPrefab, Item enemyItem)
		{
			NetworkPrefabs.RegisterNetworkPrefab(scrapPrefab);
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && !singleton.NetworkConfig.Prefabs.Contains(scrapPrefab))
			{
				singleton.AddNetworkPrefab(scrapPrefab);
			}
			Items.RegisterItem(enemyItem);
			Items.RegisterScrap(enemyItem, 0, (LevelTypes)1);
			AllEnemiesScraps.Add(enemyItem);
			Enemies2Props.Add(enemyName, scrapPrefab);
			Plugin.logger.LogInfo((object)("Registered NetworkPrefab '" + ((Object)scrapPrefab).name + "' (" + enemyItem.itemName + ")"));
		}

		public static void CleanEnemyObj(GameObject enemyObj)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			try
			{
				if (((Object)enemyObj).name.Contains("SandSpider"))
				{
					return;
				}
				int num = (Object.op_Implicit((Object)(object)Camera.main) ? Camera.main.cullingMask : 591075327);
				Renderer[] componentsInChildren = enemyObj.GetComponentsInChildren<Renderer>(true);
				Animator component = enemyObj.GetComponent<Animator>();
				if ((Object)(object)component != (Object)null)
				{
					component.Update(0f);
				}
				Plugin.logger.LogInfo((object)("Starting cleanup on '" + ((Object)enemyObj).name + "'"));
				Renderer[] array = componentsInChildren;
				foreach (Renderer val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						bool enabled = val.enabled;
						bool flag = ((1 << ((Component)val).gameObject.layer) & num) != 0;
						if (!enabled || !flag)
						{
							Plugin.logger.LogInfo((object)("Removing renderer '" + ((Object)val).name + "' from '" + ((Object)enemyObj).name + "'"));
							Object.DestroyImmediate((Object)(object)val);
						}
						SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
						if (val2 != null)
						{
							Mesh val3 = new Mesh();
							val2.BakeMesh(val3);
						}
					}
				}
				Plugin.logger.LogInfo((object)("Cleanup completed on '" + ((Object)enemyObj).name + "'"));
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"ERROR cleaning '{((Object)enemyObj).name}': {arg}");
			}
		}
	}
	[Serializable]
	[JsonObject(Description = "The value of a mob once killed, if it can be killed.")]
	public record struct EnemyData
	{
		[Serializable]
		[JsonObject(Description = "The metadata of a mob once killed, if it can be killed.")]
		public record struct EnemyMetadata
		{
			public Vec3 MeshOffset;

			public Vec3 HandRotation;

			public Vec3 FloorRotation;

			public Vec3 CollisionExtents;

			public bool AnimateOnDeath;

			public bool TwoHanded;

			public string DropSFX;

			public string GrabSFX;

			public string PocketSFX;

			public Dictionary<string, float> LootTable;

			[JsonConstructor]
			public EnemyMetadata()
			{
				DropSFX = "default";
				GrabSFX = "none";
				PocketSFX = "none";
				MeshOffset = default(Vec3);
				HandRotation = default(Vec3);
				FloorRotation = default(Vec3);
				CollisionExtents = new Vec3(1.5f, 1.5f, 1.5f);
				AnimateOnDeath = false;
				TwoHanded = true;
				DropSFX = "default";
				GrabSFX = "none";
				PocketSFX = "none";
				LootTable = new Dictionary<string, float>();
			}

			public EnemyMetadata(Vec3 meshOffset = default(Vec3), Vec3 handRotation = default(Vec3), Vec3 floorRotation = default(Vec3), bool animateOnDeath = true, bool twoHanded = true, Dictionary<string, float>? loots = null, string dropsfx = "default", string grabsfx = "none", string pocketsfx = "none", Vec3? collisionSize = null)
			{
				DropSFX = "default";
				GrabSFX = "none";
				PocketSFX = "none";
				MeshOffset = meshOffset;
				HandRotation = handRotation;
				FloorRotation = floorRotation;
				CollisionExtents = collisionSize ?? new Vec3(1.5f, 1.5f, 1.5f);
				AnimateOnDeath = animateOnDeath;
				TwoHanded = twoHanded;
				DropSFX = dropsfx;
				GrabSFX = grabsfx;
				PocketSFX = pocketsfx;
				LootTable = loots ?? new Dictionary<string, float>();
			}
		}

		[JsonIgnore]
		public readonly float LCMass => Mass / 105f + 1f;

		public bool Pickupable;

		public int MinValue;

		public int MaxValue;

		public float Mass;

		public string Rank;

		public EnemyMetadata Metadata;

		[JsonConstructor]
		public EnemyData()
		{
			Pickupable = true;
			MinValue = 80;
			MaxValue = 110;
			Mass = 50f;
			Rank = "C";
			Metadata = new EnemyMetadata();
		}

		public EnemyData(bool pickupable = true, int minValue = 80, int maxValue = 250, float mass = 50f, string rank = "E", EnemyMetadata? metadata = null)
		{
			Pickupable = pickupable;
			MinValue = minValue;
			MaxValue = maxValue;
			Mass = mass;
			Rank = rank;
			Metadata = metadata ?? new EnemyMetadata();
		}

		[CompilerGenerated]
		private readonly bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Pickupable = ");
			builder.Append(Pickupable.ToString());
			builder.Append(", MinValue = ");
			builder.Append(MinValue.ToString());
			builder.Append(", MaxValue = ");
			builder.Append(MaxValue.ToString());
			builder.Append(", Mass = ");
			builder.Append(Mass.ToString());
			builder.Append(", Rank = ");
			builder.Append((object?)Rank);
			builder.Append(", Metadata = ");
			builder.Append(Metadata.ToString());
			builder.Append(", LCMass = ");
			builder.Append(LCMass.ToString());
			return true;
		}
	}
	[Serializable]
	[JsonObject(Description = "A simple and flexible Vector3 structure.")]
	public record struct Vec3
	{
		public float X;

		public float Y;

		public float Z;

		[JsonConstructor]
		public Vec3(float x, float y, float z)
		{
			Z = 0f;
			X = x;
			Y = y;
			Z = z;
		}

		public static implicit operator Vector3(Vec3 v)
		{
			return new Vector3(v.X, v.Y, v.Z);
		}

		public static implicit operator Vector3(Vec3 v)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.X, v.Y, v.Z);
		}

		public static implicit operator Vec3(Vector3 v)
		{
			return new Vec3(v.X, v.Y, v.Z);
		}

		public static implicit operator Vec3(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vec3(v.x, v.y, v.z);
		}

		public static Vec3 operator *(Vec3 l, float r)
		{
			return new Vec3(l.X * r, l.Y * r, l.Z * r);
		}

		public static Vec3 operator *(Vec3 l, Vec3 r)
		{
			return new Vec3(l.X * r.X, l.Y * r.Y, l.Z * r.Z);
		}

		public static Vec3 operator /(Vec3 l, float r)
		{
			return new Vec3(l.X / r, l.Y / r, l.Z / r);
		}

		public static Vec3 operator /(Vec3 l, Vec3 r)
		{
			return new Vec3(l.X / r.X, l.Y / r.Y, l.Z / r.Z);
		}

		public static Vec3 operator +(Vec3 l, Vec3 r)
		{
			return new Vec3(l.X + r.X, l.Y + r.Y, l.Z + r.Z);
		}

		public static Vec3 operator -(Vec3 l, Vec3 r)
		{
			return new Vec3(l.X - r.X, l.Y - r.Y, l.Z - r.Z);
		}

		public static Vec3 operator -(Vec3 s)
		{
			return new Vec3(0f - s.X, 0f - s.Y, 0f - s.Z);
		}

		public static float operator ~(Vec3 l)
		{
			return l.Length();
		}

		public readonly float Length()
		{
			return (float)Math.Sqrt(Math.Pow(X, 2.0) + Math.Pow(Y, 2.0) + Math.Pow(Z, 2.0));
		}

		public readonly void Deconstruct(out float x, out float y, out float z)
		{
			x = X;
			y = Y;
			z = Z;
		}

		public readonly void Deconstruct(out float x, out float y)
		{
			x = X;
			y = Y;
		}
	}
	internal static class FarmingAndCookingSupport
	{
		private const string FarmingAndCookingGuid = "MelanieMelicious.FarmAndCook";

		private static bool? farmingAndCookingLoaded;

		public static bool FarmingAndCookingLoaded
		{
			get
			{
				bool valueOrDefault = farmingAndCookingLoaded.GetValueOrDefault();
				if (!farmingAndCookingLoaded.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("MelanieMelicious.FarmAndCook");
					farmingAndCookingLoaded = valueOrDefault;
				}
				return farmingAndCookingLoaded.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void RegisterFarmingAndCookingBodies(List<Item> bodies)
		{
			foreach (Item body in bodies)
			{
				Plugin.bodyHash.Add(body);
				Plugin.logger.LogDebug((object)("Registered " + body.itemName + " for MelanieMeliciousCooked plugin."));
			}
			Plugin.logger.LogInfo((object)"Successfully registered all the corpses as grindable for the Farming & Cooking mod.");
		}
	}
	internal static class FastResourcesManager
	{
		public static AssetBundle Resources;

		public static readonly Dictionary<string, AudioClip> CustomAudioClips;

		public static Sprite EnemyScrapIcon { get; private set; }

		public static AudioClip EnemyDropDefaultSound { get; private set; }

		public static string CustomSoundsFolder => Path.Combine(Paths.ConfigPath, "EnhancedMonsters", "CustomSFX");

		static FastResourcesManager()
		{
			CustomAudioClips = new Dictionary<string, AudioClip>();
			string name = Assembly.GetExecutingAssembly().GetManifestResourceNames()[0];
			Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
			Resources = AssetBundle.LoadFromStream(manifestResourceStream);
			EnemyScrapIcon = Resources.LoadAsset<Sprite>("EnemyScrapItemIcon");
			EnemyDropDefaultSound = Resources.LoadAsset<AudioClip>("BodyDrop");
			LoadCustomSounds();
		}

		private static void LoadCustomSounds()
		{
			if (!Directory.Exists(CustomSoundsFolder))
			{
				Directory.CreateDirectory(CustomSoundsFolder);
				Plugin.logger.LogInfo((object)("CustomSFX folder didn't exist, created at " + CustomSoundsFolder));
			}
			string[] files = Directory.GetFiles(CustomSoundsFolder, "*.wav", SearchOption.TopDirectoryOnly);
			int num = 0;
			string[] array = files;
			foreach (string text in array)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				if (fileNameWithoutExtension == "default" || fileNameWithoutExtension == "none")
				{
					Plugin.logger.LogWarning((object)("Skipping '" + Path.GetFileName(text) + "': '" + fileNameWithoutExtension + "' is a reserved SFX key."));
					continue;
				}
				if (CustomAudioClips.ContainsKey(fileNameWithoutExtension))
				{
					Plugin.logger.LogWarning((object)("Skipping '" + Path.GetFileName(text) + "': key '" + fileNameWithoutExtension + "' already loaded."));
					continue;
				}
				try
				{
					AudioClip value = LoadWav(text, fileNameWithoutExtension);
					CustomAudioClips[fileNameWithoutExtension] = value;
					num = checked(num + 1);
					Plugin.logger.LogInfo((object)("Loaded custom SFX '" + fileNameWithoutExtension + "' from " + Path.GetFileName(text)));
				}
				catch (Exception ex)
				{
					Plugin.logger.LogError((object)("Failed to load '" + Path.GetFileName(text) + "': " + ex.Message));
				}
			}
			Plugin.logger.LogInfo((object)$"CustomSFX loading complete: {num} clip(s) loaded from {CustomSoundsFolder}");
		}

		private static AudioClip LoadWav(string filePath, string key)
		{
			using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
			using BinaryReader binaryReader = new BinaryReader(fileStream);
			if (FourCC(binaryReader) != "RIFF")
			{
				throw new InvalidDataException("Not a RIFF file");
			}
			binaryReader.ReadInt32();
			if (FourCC(binaryReader) != "WAVE")
			{
				throw new InvalidDataException("Not a WAVE file");
			}
			short num = 0;
			short num2 = 0;
			int num3 = 0;
			short num4 = 0;
			byte[] array = null;
			checked
			{
				while (fileStream.Position < fileStream.Length)
				{
					string text = FourCC(binaryReader);
					int num5 = binaryReader.ReadInt32();
					if (text == "fmt ")
					{
						num = binaryReader.ReadInt16();
						num2 = binaryReader.ReadInt16();
						num3 = binaryReader.ReadInt32();
						binaryReader.ReadInt32();
						binaryReader.ReadInt16();
						num4 = binaryReader.ReadInt16();
						int num6 = 16;
						if ((ushort)num == 65534 && num5 >= 40)
						{
							binaryReader.ReadInt16();
							binaryReader.ReadInt16();
							binaryReader.ReadInt32();
							byte[] value = binaryReader.ReadBytes(16);
							num6 += 24;
							switch (BitConverter.ToInt32(value, 0))
							{
							case 1:
								num = 1;
								break;
							case 3:
								num = 3;
								break;
							}
						}
						if (num5 > num6)
						{
							fileStream.Seek(num5 - num6, SeekOrigin.Current);
						}
					}
					else
					{
						if (text == "data")
						{
							array = binaryReader.ReadBytes(num5);
							break;
						}
						fileStream.Seek(num5, SeekOrigin.Current);
					}
				}
				if (array == null)
				{
					throw new InvalidDataException("No 'data' chunk found");
				}
			}
			float[] array2;
			if (num == 1 && num4 == 16)
			{
				int num7 = array.Length / 2;
				array2 = new float[num7];
				checked
				{
					for (int i = 0; i < num7; i++)
					{
						short num8 = (short)(array[i * 2] | (array[i * 2 + 1] << 8));
						array2[i] = (float)num8 / 32768f;
					}
				}
			}
			else if (num == 1 && num4 == 24)
			{
				int num9 = array.Length / 3;
				array2 = new float[num9];
				for (int j = 0; j < num9; j = checked(j + 1))
				{
					int num10 = checked(array[j * 3] | (array[j * 3 + 1] << 8) | (array[j * 3 + 2] << 16));
					if (((uint)num10 & 0x800000u) != 0)
					{
						num10 |= -16777216;
					}
					array2[j] = (float)num10 / 8388608f;
				}
			}
			else if (num == 1 && num4 == 32)
			{
				int num11 = array.Length / 4;
				array2 = new float[num11];
				checked
				{
					for (int k = 0; k < num11; k++)
					{
						int num12 = array[k * 4] | (array[k * 4 + 1] << 8) | (array[k * 4 + 2] << 16) | (array[k * 4 + 3] << 24);
						array2[k] = (float)num12 / 2.1474836E+09f;
					}
				}
			}
			else
			{
				if (num != 3 || num4 != 32)
				{
					throw new InvalidDataException($"Unsupported WAV format (format={num}, bits={num4}). Use 16/24/32-bit PCM or 32-bit IEEE float.");
				}
				int num13 = array.Length / 4;
				array2 = new float[num13];
				Buffer.BlockCopy(array, 0, array2, 0, array.Length);
			}
			int num14 = array2.Length / num2;
			AudioClip val = AudioClip.Create("EM_CSFX_" + key, num14, (int)num2, num3, false);
			val.SetData(array2, 0);
			return val;
		}

		private static string FourCC(BinaryReader reader)
		{
			return Encoding.ASCII.GetString(reader.ReadBytes(4));
		}
	}
	internal static class KnownEnemies
	{
		public const string BunkerSpider = "Bunker Spider";

		public const string Flowerman = "Flowerman";

		public const string SandSpider = "SandSpider";

		public const string Maneater = "Maneater";
	}
	public static class Utility
	{
		public const float KgToLb = 2.2046227f;

		public static string ToStringObj(this object obj, string prefix = "")
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(prefix + obj.GetType().FullName + ": {");
			FieldInfo[] fields = obj.GetType().GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				object arg = fieldInfo.GetValue(obj) ?? null;
				stringBuilder.AppendLine(prefix + $"\t{fieldInfo.FieldType.Name} {fieldInfo.Name}: {arg}");
			}
			stringBuilder.AppendLine(prefix + "}");
			return stringBuilder.ToString();
		}

		public static T EnsureComponent<T>(this GameObject go) where T : Component
		{
			if (go == null)
			{
				throw new NullReferenceException("The gameObject is a null reference.");
			}
			T result = default(T);
			if (!go.TryGetComponent<T>(ref result))
			{
				return go.AddComponent<T>();
			}
			return result;
		}

		public static void AddRange<K, T, TI>(this IDictionary<K, T> target, IEnumerable<TI> source, Func<TI, K> key, Func<TI, T> selector, bool set = true)
		{
			foreach (TI item in source)
			{
				K key2 = key(item);
				T value = selector(item);
				if (set)
				{
					target[key2] = value;
				}
				else
				{
					target.TryAdd(key(item), selector(item));
				}
			}
		}

		public static void ProperConcat<K, T>(this IDictionary<K, T> target, IDictionary<K, T> source)
		{
			foreach (KeyValuePair<K, T> item in source)
			{
				if (!target.ContainsKey(item.Key))
				{
					target.Add(item.Key, item.Value);
				}
			}
		}

		public static void RemoveComponentsInChildren<T>(this GameObject go) where T : Component
		{
			T[] componentsInChildren = go.GetComponentsInChildren<T>();
			T[] array = componentsInChildren;
			foreach (T val in array)
			{
				Plugin.logger.LogDebug((object)("Destroying component " + ((object)val).GetType().Name + " on " + ((Object)(object)val).name + " (child of " + ((Object)go).name + ")"));
				Object.Destroy((Object)(object)val);
			}
		}

		internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type t) => t != null);
			}
		}
	}
}
namespace EnhancedMonsters.Patches
{
	[HarmonyPatch(typeof(EnemyAI))]
	public class EnemyAI_Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(EnemyAI), "Start")]
		private static void Start(EnemyAI __instance)
		{
			if (__instance.enemyType == null)
			{
				return;
			}
			SyncedConfig syncedConfig = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance : SyncedConfig.Default);
			if (!syncedConfig.EnemiesData.TryGetValue(__instance.enemyType.enemyName, out var value))
			{
				Plugin.logger.LogWarning((object)("Enemy " + __instance.enemyType.enemyName + " is not registered in the enemies data. Registering it now."));
				value = new EnemyData(pickupable: true, 80, 250, 50f, "E", null);
				EnemiesDataManager.RegisterEnemy(__instance.enemyType.enemyName, value);
			}
			if (!(value.Rank == string.Empty))
			{
				ScanNodeProperties componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<ScanNodeProperties>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.subText = "Rank " + value.Rank;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		private static void KillEnemy(EnemyAI __instance, bool destroy)
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.enemyType == (Object)null)
			{
				return;
			}
			Plugin.logger.LogDebug((object)("Mob " + __instance.enemyType.enemyName + " died."));
			if (destroy)
			{
				return;
			}
			if (!SyncedConfig.Instance.EnemiesData.ContainsKey(__instance.enemyType.enemyName))
			{
				EnemiesDataManager.RegisterEnemy(__instance.enemyType.enemyName, new EnemyData(pickupable: true, 80, 250, 50f, "E", null));
				Plugin.logger.LogInfo((object)("Mob was not registered. Registered it with name '" + __instance.enemyType.enemyName + "'"));
			}
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			Plugin.logger.LogDebug((object)("Spawning EnemyScrap for enemy " + __instance.enemyType.enemyName + "."));
			if (!EnemiesDataManager.Enemies2Props.TryGetValue(__instance.enemyType.enemyName, out GameObject value))
			{
				Plugin.logger.LogWarning((object)("Mob " + __instance.enemyType.enemyName + " has no enemy2prop prefab."));
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(value);
			((Object)val).hideFlags = (HideFlags)0;
			val.transform.position = ((Component)__instance).transform.position;
			val.GetComponent<NetworkObject>().Spawn(false);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(-10000f, -10000f, -10000f);
			((Component)__instance).transform.position = val2;
			__instance.serverPosition = val2;
			NetworkObject component = ((Component)__instance).GetComponent<NetworkObject>();
			EnhancedMonstersNetworkHandler instance = EnhancedMonstersNetworkHandler.Instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)component != (Object)null)
			{
				instance.HideOriginalEnemyBodyClientRpc(NetworkObjectReference.op_Implicit(component), val2);
			}
			else
			{
				Plugin.logger.LogWarning((object)"Network handler or enemy NetworkObject unavailable; falling back to SyncPositionToClients()");
				__instance.SyncPositionToClients();
			}
			Plugin.logger.LogDebug((object)"Mob should now be grabbable for all users.");
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManager_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch("StartDisconnect")]
		public static void StartDisconnect()
		{
			SyncedConfig.RevertSync();
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	public class MenuManager_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuManager), "Start")]
		private static void Start(MenuManager __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance))
			{
				Plugin.logger.LogError((object)"MenuManager instance is null. Something might have booted too early.");
				return;
			}
			if (__instance.versionNumberText == null)
			{
				Plugin.logger.LogWarning((object)"It seems like the Version Number Text of main menu is missing, it's probably the first main menu iteration. Skipping this one.");
				return;
			}
			TextMeshProUGUI versionNumberText = __instance.versionNumberText;
			((TMP_Text)versionNumberText).text = ((TMP_Text)versionNumberText).text + "\n<size=75%>Enhanced Monsters v1.4.0</size>";
			((Component)__instance.versionNumberText).gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(500f, 50f);
			EnemiesDataManager.ScanAndRegisterUnknownEnemies();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
			Plugin.logger.LogInfo((object)"All enemies have been patched correctly.");
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerB_Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayerPrefabs()
		{
			EnemiesDataManager.ScanAndRegisterUnknownEnemies();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
		}

		[HarmonyPostfix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			if (SyncedConfig.IsHost)
			{
				Plugin.logger.LogInfo((object)"Local player is host, no sync request needed");
			}
			else
			{
				SyncedConfig.RequestSync();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRound_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void StartPatch()
		{
			EnemiesDataManager.ScanAndRegisterUnknownEnemies();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && (Object)(object)Plugin.NetworkHandlerPrefab != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(Plugin.NetworkHandlerPrefab);
				val.GetComponent<NetworkObject>().Spawn(true);
				Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler spawned by server in StartOfRound");
			}
		}
	}
}
namespace EnhancedMonsters.Networking
{
	public class EnhancedMonstersNetworkHandler : NetworkBehaviour
	{
		public static EnhancedMonstersNetworkHandler Instance { get; private set; }

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			Instance = this;
			if (((NetworkBehaviour)this).IsServer)
			{
				ConfigSyncService.Synced = true;
			}
			Plugin.logger.LogInfo((object)("EnhancedMonstersNetworkHandler spawned (" + (((NetworkBehaviour)this).IsServer ? "server" : "client") + ")"));
		}

		public override void OnNetworkDespawn()
		{
			((NetworkBehaviour)this).OnNetworkDespawn();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler despawned");
		}

		[ServerRpc(RequireOwnership = false)]
		public void RequestConfigSyncServerRpc(ServerRpcParams serverRpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3276370873u, serverRpcParams, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 3276370873u, serverRpcParams, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (((NetworkBehaviour)this).IsServer)
			{
				ulong senderClientId = serverRpcParams.Receive.SenderClientId;
				Plugin.logger.LogDebug((object)$"ConfigSync request received from client {senderClientId}");
				byte[] array = ConfigSyncService.SerializeCurrent();
				if (array.Length == 0)
				{
					Plugin.logger.LogError((object)"Aborting sync response: empty payload");
					return;
				}
				ClientRpcParams val2 = default(ClientRpcParams);
				val2.Send = new ClientRpcSendParams
				{
					TargetClientIds = new ulong[1] { senderClientId }
				};
				ClientRpcParams clientRpcParams = val2;
				ReceiveConfigSyncClientRpc(array, clientRpcParams);
			}
		}

		[ClientRpc]
		public void ReceiveConfigSyncClientRpc(byte[] data, ClientRpcParams clientRpcParams = default(ClientRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2833577898u, clientRpcParams, (RpcDelivery)0);
				bool flag = data != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<byte>(data, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 2833577898u, clientRpcParams, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				if (!((NetworkBehaviour)this).IsServer)
				{
					Plugin.logger.LogInfo((object)$"Received config sync via ClientRpc, {((data != null) ? data.Length : 0)} bytes");
					ConfigSyncService.ApplyReceivedSync(data);
				}
			}
		}

		[ClientRpc]
		public void BroadcastConfigSyncClientRpc(byte[] data)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(149726897u, val, (RpcDelivery)0);
				bool flag = data != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(data, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 149726897u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				if (!((NetworkBehaviour)this).IsServer)
				{
					Plugin.logger.LogInfo((object)$"Received config broadcast via ClientRpc, {((data != null) ? data.Length : 0)} bytes");
					ConfigSyncService.ApplyReceivedSync(data);
				}
			}
		}

		[ClientRpc]
		public void HideOriginalEnemyBodyClientRpc(NetworkObjectReference originalEnemyRef, Vector3 hidePosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1086037223u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref originalEnemyRef, default(ForNetworkSerializable));
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref hidePosition);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1086037223u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			NetworkObject val3 = default(NetworkObject);
			if (!((NetworkObjectReference)(ref originalEnemyRef)).TryGet(ref val3, (NetworkManager)null))
			{
				Plugin.logger.LogWarning((object)"HideOriginalEnemyBodyClientRpc: could not resolve enemy NetworkObject; skipping client-side teleport");
				return;
			}
			((Component)val3).transform.position = hidePosition;
			EnemyAI component = ((Component)val3).GetComponent<EnemyAI>();
			if ((Object)(object)component != (Object)null)
			{
				component.serverPosition = hidePosition;
			}
			Plugin.logger.LogDebug((object)$"Hid original enemy body '{((Object)((Component)val3).gameObject).name}' at {hidePosition}");
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(3276370873u, new RpcReceiveHandler(__rpc_handler_3276370873), "RequestConfigSyncServerRpc");
			((NetworkBehaviour)this).__registerRpc(2833577898u, new RpcReceiveHandler(__rpc_handler_2833577898), "ReceiveConfigSyncClientRpc");
			((NetworkBehaviour)this).__registerRpc(149726897u, new RpcReceiveHandler(__rpc_handler_149726897), "BroadcastConfigSyncClientRpc");
			((NetworkBehaviour)this).__registerRpc(1086037223u, new RpcReceiveHandler(__rpc_handler_1086037223), "HideOriginalEnemyBodyClientRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_3276370873(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ServerRpcParams server = rpcParams.Server;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((EnhancedMonstersNetworkHandler)(object)target).RequestConfigSyncServerRpc(server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2833577898(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				byte[] data = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref data, default(ForPrimitives));
				}
				ClientRpcParams client = rpcParams.Client;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((EnhancedMonstersNetworkHandler)(object)target).ReceiveConfigSyncClientRpc(data, client);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_149726897(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0088: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				byte[] data = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref data, default(ForPrimitives));
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((EnhancedMonstersNetworkHandler)(object)target).BroadcastConfigSyncClientRpc(data);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1086037223(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkObjectReference originalEnemyRef = default(NetworkObjectReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref originalEnemyRef, default(ForNetworkSerializable));
				Vector3 hidePosition = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref hidePosition);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((EnhancedMonstersNetworkHandler)(object)target).HideOriginalEnemyBodyClientRpc(originalEnemyRef, hidePosition);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "EnhancedMonstersNetworkHandler";
		}
	}
}
namespace EnhancedMonsters.Monobehaviours
{
	public class EnemyScrap : GrabbableObject
	{
		[CompilerGenerated]
		private sealed class <DisableAnimatorOnAnimationEnd>d__22 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemyScrap <>4__this;

			private AnimatorClipInfo[] <currentClip>5__1;

			private float <deathAnimDuration>5__2;

			private float <deathAnimProgress>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0074: 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_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<currentClip>5__1 = <>4__this.EnemyAnimator.GetCurrentAnimatorClipInfo(0);
					if (<currentClip>5__1.Length < 1)
					{
						return false;
					}
					<deathAnimDuration>5__2 = ((AnimatorClipInfo)(ref <currentClip>5__1[0])).clip.length;
					AnimatorStateInfo currentAnimatorStateInfo = <>4__this.EnemyAnimator.GetCurrentAnimatorStateInfo(0);
					<deathAnimProgress>5__3 = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<deathAnimProgress>5__3 < <deathAnimDuration>5__2)
				{
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				}
				((Behaviour)<>4__this.EnemyAnimator).enabled = false;
				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();
			}
		}

		public EnemyType enemyType;

		private readonly NetworkVariable<int> _syncedScrapValue = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public Animator EnemyAnimator { get; private set; }

		public ScanNodeProperties ScanNode { get; private set; }

		public GameObject EnemyGameObject { get; set; }

		public EnemyData EnemyData => LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName];

		public int SyncedScrapValue
		{
			get
			{
				return _syncedScrapValue.Value;
			}
			set
			{
				_syncedScrapValue.Value = value;
			}
		}

		private void Awake()
		{
			EnemyAnimator = ((Component)this).gameObject.GetComponentInChildren<Animator>();
			if ((Object)(object)EnemyAnimator == (Object)null)
			{
				Plugin.logger.LogWarning((object)("So somehow, the monster " + ((Object)((Component)this).gameObject).name + " does not have any Animator. Will work anyway but might have its animations glitched"));
			}
			ScanNode = ((Component)this).gameObject.GetComponentInChildren<ScanNodeProperties>();
			if ((Object)(object)ScanNode == (Object)null)
			{
				Plugin.logger.LogWarning((object)("No ScanNode found in " + ((Object)((Component)this).gameObject).name + ". That's a weird enemy..."));
			}
			if (!base.itemProperties.saveItemVariable)
			{
				Plugin.logger.LogError((object)("Error: Enemy corpse saving was set to false for " + enemyType.enemyName));
			}
		}

		public override void Start()
		{
			((GrabbableObject)this).Start();
			if (((NetworkBehaviour)this).IsServer)
			{
				Plugin.logger.LogInfo((object)"Synchronizing the mob data and scrap values and positions with clients...");
				EnemyData enemyData = SyncedConfig.Instance.EnemiesData[enemyType.enemyName];
				if (GameNetworkManager.Instance.gameHasStarted || base.scrapValue == 0)
				{
					int syncedScrapValue = new Random().Next(enemyData.MinValue, enemyData.MaxValue);
					SyncedScrapValue = syncedScrapValue;
				}
				else
				{
					SyncedScrapValue = base.scrapValue;
				}
			}
			Plugin.logger.LogInfo((object)("Mob scrap " + enemyType.enemyName + " has spawned !"));
			if ((Object)(object)EnemyAnimator != (Object)null)
			{
				if (!EnemyData.Metadata.AnimateOnDeath)
				{
					((Behaviour)EnemyAnimator).enabled = false;
				}
				try
				{
					EnemyAnimator.SetLayerWeight(2, 0f);
				}
				catch (Exception arg)
				{
					Plugin.logger.LogWarning((object)$"Failed to set layer 2's weight to 0 (bracken fix?). Error: {arg}");
					((Behaviour)EnemyAnimator).enabled = false;
				}
				try
				{
					EnemyAnimator.SetBool("Stunned", false);
					EnemyAnimator.SetBool("stunned", false);
					EnemyAnimator.SetBool("stun", false);
					EnemyAnimator.SetTrigger("KillEnemy");
					EnemyAnimator.SetBool("Dead", true);
					((MonoBehaviour)this).StartCoroutine(DisableAnimatorOnAnimationEnd());
				}
				catch (Exception arg2)
				{
					Plugin.logger.LogError((object)$"Failed to set the enemy {((Object)((Component)this).gameObject).name} mob mesh animator to dead state. Maybe the animator doesn't have a dead state ? Error: {arg2}");
					((Behaviour)EnemyAnimator).enabled = false;
				}
				if (enemyType.enemyName == "Flowerman")
				{
					((Component)EnemyAnimator).gameObject.SetActive(false);
					((Component)EnemyAnimator).gameObject.SetActive(true);
					((Behaviour)EnemyAnimator).enabled = false;
				}
			}
			if (Object.op_Implicit((Object)(object)ScanNode))
			{
				EnemyData enemyData2 = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName]);
				ScanNodeProperties component = ((Component)ScanNode).GetComponent<ScanNodeProperties>();
				component.scrapValue = SyncedScrapValue;
				component.subText = $"Rank:{enemyData2.Rank}\nValue: ${SyncedScrapValue}";
			}
			else
			{
				Plugin.logger.LogError((object)("Enemy corpse " + base.itemProperties.itemName + " is missing a ScanNode !"));
			}
		}

		public void SetScrapValue(int value)
		{
			Plugin.logger.LogInfo((object)$"Setting scrap value for {base.itemProperties.itemName}: {value}");
			base.scrapValue = value;
			ScanNode.scrapValue = value;
			EnemyData enemyData = (LocalConfig.Singleton.synchronizeRanks.Value ? SyncedConfig.Instance.EnemiesData[enemyType.enemyName] : SyncedConfig.Default.EnemiesData[enemyType.enemyName]);
			ScanNode.subText = $"Rank: {enemyData.Rank}\nValue: {value}";
		}

		[IteratorStateMachine(typeof(<DisableAnimatorOnAnimationEnd>d__22))]
		public IEnumerator DisableAnimatorOnAnimationEnd()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DisableAnimatorOnAnimationEnd>d__22(0)
			{
				<>4__this = this
			};
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			((NetworkVariableBase)_syncedScrapValue).Initialize((NetworkBehaviour)(object)this);
			NetworkVariable<int> syncedScrapValue = _syncedScrapValue;
			syncedScrapValue.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Combine((Delegate?)(object)syncedScrapValue.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate<int>)delegate(int oldVal, int newVal)
			{
				SetScrapValue(newVal);
			});
		}

		public override int GetItemDataToSave()
		{
			Plugin.logger.LogInfo((object)("GetItemData: Trying to save enemy scrap for " + base.itemProperties.itemName + "."));
			return 0;
		}

		protected override void __initializeVariables()
		{
			if (_syncedScrapValue == null)
			{
				throw new Exception("EnemyScrap._syncedScrapValue cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_syncedScrapValue).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_syncedScrapValue, "_syncedScrapValue");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_syncedScrapValue);
			((GrabbableObject)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			((GrabbableObject)this).__initializeRpcs();
		}

		protected internal override string __getTypeName()
		{
			return "EnemyScrap";
		}
	}
	public class SpiderArachnophobiaToggle : MonoBehaviour
	{
		private MeshRenderer _safeMesh;

		private SkinnedMeshRenderer _normalMesh;

		private bool _renderersResolved;

		private void Start()
		{
			ResolveRenderers();
			ApplyArachnophobeMode(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
		}

		private void LateUpdate()
		{
			ApplyArachnophobeMode(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
		}

		public void ApplyArachnophobeMode(bool arachnophobeEnabled)
		{
			if (!_renderersResolved)
			{
				ResolveRenderers();
			}
			if (!((Object)(object)_safeMesh == (Object)null) && !((Object)(object)_normalMesh == (Object)null))
			{
				if (((Renderer)_safeMesh).enabled != arachnophobeEnabled)
				{
					((Renderer)_safeMesh).enabled = arachnophobeEnabled;
				}
				if (((Renderer)_normalMesh).enabled != !arachnophobeEnabled)
				{
					((Renderer)_normalMesh).enabled = !arachnophobeEnabled;
				}
			}
		}

		private void ResolveRenderers()
		{
			if (((Component)this).transform.childCount == 0)
			{
				return;
			}
			Transform child = ((Component)this).transform.GetChild(0);
			Transform obj = child.Find("MeshContainer");
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = obj.Find("AnimContainer");
				if (obj3 == null)
				{
					obj2 = null;
				}
				else
				{
					Transform obj4 = obj3.Find("Armature");
					if (obj4 == null)
					{
						obj2 = null;
					}
					else
					{
						Transform obj5 = obj4.Find("Abdomen");
						obj2 = ((obj5 != null) ? obj5.Find("SpiderText") : null);
					}
				}
			}
			Transform val = (Transform)obj2;
			Transform obj6 = child.Find("MeshContainer");
			Transform val2 = ((obj6 != null) ? obj6.Find("MeshRenderer") : null);
			_safeMesh = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshRenderer>() : null);
			_normalMesh = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<SkinnedMeshRenderer>() : null);
			if ((Object)(object)_safeMesh == (Object)null || (Object)(object)_normalMesh == (Object)null)
			{
				Plugin.logger.LogError((object)"This Spider mesh doesn't have a normal mesh or an arachnophobe mesh.");
			}
			else
			{
				_renderersResolved = true;
			}
		}
	}
}
namespace EnhancedMonsters.Config
{
	internal static class ConfigSyncService
	{
		[CompilerGenerated]
		private sealed class <WaitForHandlerAndRequest>d__19 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private float <waited>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				//IL_0099: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<waited>5__1 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<waited>5__1 += 0.25f;
					break;
				}
				if ((Object)(object)EnhancedMonstersNetworkHandler.Instance == (Object)null && <waited>5__1 < 10f)
				{
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)EnhancedMonstersNetworkHandler.Instance != (Object)null)
				{
					EnhancedMonstersNetworkHandler.Instance.RequestConfigSyncServerRpc();
					Plugin.logger.LogInfo((object)$"Config sync request sent after {<waited>5__1:0.00}s wait");
				}
				else
				{
					Plugin.logger.LogWarning((object)$"Config sync handler did not appear within {10f}s, giving up");
				}
				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();
			}
		}

		public static SyncedConfig Default { get; private set; }

		public static SyncedConfig Instance { get; private set; }

		public static bool Synced { get; internal set; }

		public static bool IsHost
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				return singleton != null && singleton.IsHost;
			}
		}

		public static bool IsClient
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				return singleton != null && singleton.IsClient;
			}
		}

		public static void Initialize(SyncedConfig defaults)
		{
			Default = defaults;
			Instance = defaults;
			Synced = false;
		}

		public static void RevertSync()
		{
			Instance = Default;
			Synced = false;
			Plugin.logger.LogInfo((object)"Reverting sync, Instance=Default, Synced=false");
		}

		public static void RequestSync()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!IsClient || IsHost)
			{
				return;
			}
			if ((Object)(object)EnhancedMonstersNetworkHandler.Instance != (Object)null)
			{
				EnhancedMonstersNetworkHandler.Instance.RequestConfigSyncServerRpc();
				Plugin.logger.LogInfo((object)"Requesting config sync via ServerRpc");
				return;
			}
			Plugin.logger.LogInfo((object)"EnhancedMonstersNetworkHandler not yet spawned, scheduling retry");
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				((MonoBehaviour)instance).StartCoroutine(WaitForHandlerAndRequest());
			}
			else
			{
				Plugin.logger.LogWarning((object)"StartOfRound.Instance is null, cannot schedule sync retry");
			}
		}

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

		public static void BroadcastSync()
		{
			if (!IsHost)
			{
				return;
			}
			EnhancedMonstersNetworkHandler instance = EnhancedMonstersNetworkHandler.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.logger.LogDebug((object)"BroadcastSync: handler not spawned yet, skipping");
				return;
			}
			byte[] array = SerializeCurrent();
			if (array.Length != 0)
			{
				instance.BroadcastConfigSyncClientRpc(array);
				Plugin.logger.LogInfo((object)$"Host broadcast config sync, {array.Length} bytes");
			}
		}

		public static byte[] SerializeCurrent()
		{
			if (Instance == null)
			{
				Plugin.logger.LogError((object)"SerializeCurrent: Instance is null");
				return Array.Empty<byte>();
			}
			try
			{
				string s = JsonConvert.SerializeObject((object)Instance.EnemiesData);
				return Encoding.UTF8.GetBytes(s);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to serialize sync payload: {arg}");
				return Array.Empty<byte>();
			}
		}

		public static void ApplyReceivedSync(byte[] data)
		{
			if (data == null || data.Length == 0)
			{
				Plugin.logger.LogError((object)"ApplyReceivedSync: empty payload");
				return;
			}
			if (Instance == null)
			{
				Plugin.logger.LogError((object)"ApplyReceivedSync: Instance is null, cannot apply");
				return;
			}
			try
			{
				string @string = Encoding.UTF8.GetString(data);
				Dictionary<string, EnemyData> dictionary = JsonConvert.DeserializeObject<Dictionary<string, EnemyData>>(@string);
				if (dictionary == null)
				{
					Plugin.logger.LogError((object)"ApplyReceivedSync: deserialization returned null");
					return;
				}
				EnemiesDataManager.EnemiesData.Clear();
				foreach (KeyValuePair<string, EnemyData> item in dictionary)
				{
					EnemiesDataManager.EnemiesData[item.Key] = item.Value;
				}
				Synced = true;
				Plugin.logger.LogInfo((object)$"Applied sync, {dictionary.Count} entries, Synced=true");
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to apply sync payload: {arg}");
			}
		}
	}
	internal static class LethalConfigSupport
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static CanModifyDelegate <>9__3_1;

			public static GenericButtonHandler <>9__3_0;

			internal CanModifyResult <RegisterLethalConfig>b__3_1()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				return CanModifyResult.op_Implicit(!GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening);
			}

			internal void <RegisterLethalConfig>b__3_0()
			{
				GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile;
			}
		}

		private static bool? lethalConfigLoaded;

		public static bool LethalConfigLoaded
		{
			get
			{
				bool valueOrDefault = lethalConfigLoaded.GetValueOrDefault();
				if (!lethalConfigLoaded.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
					lethalConfigLoaded = valueOrDefault;
				}
				return lethalConfigLoaded.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void RegisterLethalConfig(LocalConfig config)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			LethalConfigManager.SetModDescription("Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements.");
			ConfigEntry<bool> synchronizeRanks = config.synchronizeRanks;
			BoolCheckBoxOptions val = new BoolCheckBoxOptions
			{
				Name = "Synchronize Ranks",
				Section = "General",
				RequiresRestart = false
			};
			object obj = <>c.<>9__3_1;
			if (obj == null)
			{
				CanModifyDelegate val2 = () => CanModifyResult.op_Implicit(!GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening);
				<>c.<>9__3_1 = val2;
				obj = (object)val2;
			}
			((BaseOptions)val).CanModifyCallback = (CanModifyDelegate)obj;
			BoolCheckBoxConfigItem val3 = new BoolCheckBoxConfigItem(synchronizeRanks, val);
			object obj2 = <>c.<>9__3_0;
			if (obj2 == null)
			{
				GenericButtonHandler val4 = delegate
				{
					GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile;
				};
				<>c.<>9__3_0 = val4;
				obj2 = (object)val4;
			}
			GenericButtonConfigItem val5 = new GenericButtonConfigItem("General", "Enemies Data", "All the enemies data are stored inside the file. You have a few rules to follow when editing the file or it will not work. Look at the github or thunderstore page for more info.", "Copy path", (GenericButtonHandler)obj2);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val3);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val5);
		}
	}
	internal static class LethalSettingsSupport
	{
		private static bool? lethalSettingsLoaded;

		public static bool LethalSettingsLoaded
		{
			get
			{
				bool valueOrDefault = lethalSettingsLoaded.GetValueOrDefault();
				if (!lethalSettingsLoaded.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.willis.lc.lethalsettings");
					lethalSettingsLoaded = valueOrDefault;
				}
				return lethalSettingsLoaded.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void RegisterLethalSettings(LocalConfig config)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0037: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00be: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			LocalConfig config2 = config;
			Plugin.logger.LogInfo((object)"Registering lsSyncRank");
			ToggleComponent val = new ToggleComponent
			{
				Enabled = true,
				Text = "Synchronize Ranks",
				Value = true,
				OnValueChanged = delegate(ToggleComponent comp, bool value)
				{
					config2.synchronizeRanks.Value = value;
				},
				OnInitialize = delegate(ToggleComponent comp)
				{
					comp.Value = config2.synchronizeRanks.Value;
					comp.Enabled = !GameNetworkManager.Instance.gameHasStarted || !NetworkManager.Singleton.IsListening;
				}
			};
			Plugin.logger.LogInfo((object)"Registering lsAccessEnemiesDataFile");
			ButtonComponent val2 = new ButtonComponent
			{
				Enabled = true,
				ShowCaret = true,
				Text = "Copy path to Enemies Data file",
				OnClick = delegate
				{
					GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile;
				}
			};
			Plugin.logger.LogInfo((object)"Registering mod info");
			ModSettingsConfig val3 = new ModSettingsConfig();
			val3.Id = "com.velddev.enhancedmonsters";
			val3.Name = "Enhanced Monsters";
			val3.Version = "1.4.0";
			val3.Description = "Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements.";
			val3.MenuComponents = (MenuComponent[])(object)new MenuComponent[2]
			{
				(MenuComponent)val,
				(MenuComponent)val2
			};
			ModMenu.RegisterMod(val3);
			Plugin.logger.LogInfo((object)"Registered Mod Info");
		}
	}
	public class LocalConfig
	{
		internal const string ModDesc = "Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements.";

		public readonly ConfigEntry<bool> synchronizeRanks;

		public static LocalConfig Singleton { get; private set; }

		public LocalConfig(ConfigFile cfg)
		{
			Singleton = this;
			synchronizeRanks = cfg.Bind<bool>("General", "Synchronize Ranks", true, "Wether or not to synchronize ranks of enemies from host's configs. It is recommended to keep it enabled. [NOTE: This setting can only be edited from the main menu.]");
			if (LethalConfigSupport.LethalConfigLoaded)
			{
				Plugin.logger.LogInfo((object)"Loading LethalConfig settings");
				LethalConfigSupport.RegisterLethalConfig(this);
			}
			if (LethalSettingsSupport.LethalSettingsLoaded)
			{
				Plugin.logger.LogInfo((object)"Loading LethalSettings settings");
				LethalSettingsSupport.RegisterLethalSettings(this);
			}
			Plugin.logger.LogInfo((object)"Registering all settings.");
		}
	}
	public class SyncedConfig
	{
		public Dictionary<string, EnemyData> EnemiesData;

		public ConfigFile BepInConfigs;

		public static SyncedConfig Default => ConfigSyncService.Default;

		public static SyncedConfig Instance => ConfigSyncService.Instance;

		public static bool Synced => ConfigSyncService.Synced;

		public static bool IsHost => ConfigSyncService.IsHost;

		public static bool IsClient => ConfigSyncService.IsClient;

		public SyncedConfig(ConfigFile cfg)
		{
			BepInConfigs = cfg;
			EnemiesData = EnemiesDataManager.EnemiesData;
			ConfigSyncService.Initialize(this);
		}

		public static void BroadcastSync()
		{
			ConfigSyncService.BroadcastSync();
		}

		public static void RequestSync()
		{
			ConfigSyncService.RequestSync();
		}

		public static void RevertSync()
		{
			ConfigSyncService.RevertSync();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace EnhancedMonsters.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}