Decompiled source of Enhanced Monsters v1.3.9

BepInEx/plugins/EnhancedMonsters/EnhancedMonsters.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
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.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 Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using Unity.Collections;
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.3.9")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.9.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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.3.9")]
	[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");

		public static ManualLogSource? logger;

		internal static Plugin Singleton { get; private set; }

		public static GameObject EnemyToPropPrefab { get; private set; }

		private void Awake()
		{
			Singleton = this;
			logger = ((BaseUnityPlugin)this).Logger;
			new LocalConfig(((BaseUnityPlugin)this).Config);
			logger.LogInfo((object)"Local config initialized.");
			NetcodePatcher();
			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");
			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));
			logger.LogDebug((object)"Enemy patches applied.");
			logger.LogDebug((object)"MaskedEnemy patches applied.");
			harmony.PatchAll(typeof(MenuManager_Patches));
			logger.LogDebug((object)"MenuManager patches applied.");
			harmony.PatchAll(typeof(PlayerControllerB_Patches));
			logger.LogDebug((object)"PlayerController patches applied.");
			harmony.PatchAll(typeof(GameNetworkManager_Patches));
			logger.LogDebug((object)"GameNetworkManager 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>();
			EnemyToPropPrefab = val;
		}

		private static void NetcodePatcher()
		{
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			bool flag = pluginInfos.ContainsKey("ainavt.lc.lethalconfig");
			bool flag2 = pluginInfos.ContainsKey("com.willis.lc.lethalsettings");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				bool flag3 = type.FullName.Contains(typeof(LethalConfigSupport).FullName);
				bool flag4 = type.FullName.Contains(typeof(LethalSettingsSupport).FullName);
				if ((flag3 && !flag) || (flag4 && !flag2))
				{
					continue;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const int ConfigVersion = 11;

		public const string Version = "1.3.9";

		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 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 (Synchronizable<SyncedConfig>.Instance == null || Synchronizable<SyncedConfig>.IsHost || !NetworkManager.Singleton.IsListening)
			{
				SyncedConfig.BroadcastSync();
			}
		}

		internal static void RegisterEnemy(string enemyName, EnemyData enemyData)
		{
			if (Synchronizable<SyncedConfig>.IsHost || !NetworkManager.Singleton.IsListening)
			{
				if (EnemiesData != Synchronizable<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 (!Synchronizable<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 EnsureEnemy2PropPrefabs()
		{
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			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;
				}
				Plugin.logger.LogInfo((object)("Registering NetworkPrefab '" + val.enemyType.enemyName + "'"));
				ref string enemyName = ref val.enemyType.enemyName;
				if (Enemies2Props.TryGetValue(val.enemyType.enemyName, out GameObject value))
				{
					if (!Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyName].Pickupable)
					{
						Enemies2Props.Remove(enemyName);
						continue;
					}
					EnemyScrap component = value.GetComponent<EnemyScrap>();
					component.enemyType = val.enemyType;
					((GrabbableObject)component).itemProperties.minValue = Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyName].MinValue;
					((GrabbableObject)component).itemProperties.maxValue = Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyName].MaxValue;
					((GrabbableObject)component).itemProperties.weight = Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyName].LCMass;
				}
				else
				{
					if (!Synchronizable<SyncedConfig>.Instance.EnemiesData.TryGetValue(enemyName, out var value2) || !value2.Pickupable)
					{
						continue;
					}
					GameObject val2 = new GameObject(((Object)val).name + " neutralized");
					foreach (Transform item in ((Component)val).transform)
					{
						Transform val3 = item;
						if (!((Object)val3).name.StartsWith("MapDot") && !((Object)val3).name.StartsWith("Collider") && !((Object)val3).name.StartsWith("VoiceSFX") && !((Object)val3).name.StartsWith("CreatureSFX") && !((Object)val3).name.StartsWith("SeepingSFX") && !((Object)val3).name.StartsWith("CreatureVoice") && !((Object)val3).name.StartsWith("Ambience"))
						{
							Transform val4 = Object.Instantiate<Transform>(val3);
							((Object)val4).name = ((Object)val3).name;
							((Component)val4).transform.parent = val2.transform;
						}
					}
					val2.RemoveComponentsInChildren<Collider>();
					val2.RemoveComponentsInChildren<AudioLowPassFilter>();
					val2.RemoveComponentsInChildren<AudioReverbFilter>();
					val2.RemoveComponentsInChildren<OccludeAudio>();
					val2.RemoveComponentsInChildren<EnemyAICollisionDetect>();
					val2.RemoveComponentsInChildren<AudioSource>();
					val2.RemoveComponentsInChildren<ParticleSystem>();
					val2.RemoveComponentsInChildren<ParticleSystemRenderer>();
					val2.transform.localScale = ((Component)val).transform.localScale;
					GameObject val5 = NetworkPrefabs.CloneNetworkPrefab(Plugin.EnemyToPropPrefab, ((Object)val).name + " propized");
					val2.transform.parent = val5.transform;
					Plugin.logger.LogInfo((object)("Attached " + ((Object)val2).name + " to " + ((Object)val2.transform.parent).name));
					EnemyScrap component2 = val5.GetComponent<EnemyScrap>();
					component2.EnemyGameObject = val2;
					Plugin.logger.LogInfo((object)"Set EnemyGameObject on EnemyScrap.");
					((GrabbableObject)component2).grabbable = true;
					((GrabbableObject)component2).grabbableToEnemies = false;
					component2.enemyType = val.enemyType;
					BoxCollider component3 = val5.GetComponent<BoxCollider>();
					component3.size = value2.Metadata.CollisionExtents;
					ScanNodeProperties componentInChildren = val2.GetComponentInChildren<ScanNodeProperties>();
					if (!Object.op_Implicit((Object)(object)componentInChildren))
					{
						Object.Destroy((Object)(object)val5);
						continue;
					}
					Transform transform = ((Component)componentInChildren).gameObject.transform;
					((Component)transform).transform.parent = val5.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;
					Item val6 = (((GrabbableObject)component2).itemProperties = ScriptableObject.CreateInstance<Item>());
					((Object)val6).name = enemyName + " scrap";
					val6.itemName = componentInChildren.headerText;
					val6.saveItemVariable = true;
					val6.itemIcon = FastResourcesManager.EnemyScrapIcon;
					val6.minValue = value2.MinValue;
					val6.maxValue = value2.MaxValue;
					val6.allowDroppingAheadOfPlayer = true;
					val6.canBeGrabbedBeforeGameStart = true;
					val6.isScrap = true;
					val6.itemSpawnsOnGround = false;
					val6.twoHanded = value2.Metadata.TwoHanded;
					val6.requiresBattery = false;
					val6.twoHandedAnimation = value2.Metadata.TwoHanded;
					val6.weight = value2.LCMass;
					val6.spawnPrefab = val5;
					val6.restingRotation = value2.Metadata.FloorRotation;
					val6.rotationOffset = value2.Metadata.HandRotation;
					val6.positionOffset = value2.Metadata.MeshOffset;
					EnemyData enemyData = Synchronizable<SyncedConfig>.Default.EnemiesData[enemyName];
					AudioClip value3;
					if (enemyData.Metadata.DropSFX == "default")
					{
						val6.dropSFX = FastResourcesManager.EnemyDropDefaultSound;
					}
					else if (FastResourcesManager.CustomAudioClips.TryGetValue(enemyData.Metadata.DropSFX, out value3))
					{
						val6.dropSFX = value3;
					}
					else
					{
						val6.dropSFX = null;
					}
					AudioClip value4;
					if (enemyData.Metadata.GrabSFX == "default")
					{
						val6.grabSFX = FastResourcesManager.EnemyDropDefaultSound;
					}
					else if (FastResourcesManager.CustomAudioClips.TryGetValue(enemyData.Metadata.GrabSFX, out value4))
					{
						val6.grabSFX = value4;
					}
					else
					{
						val6.grabSFX = null;
					}
					AudioClip value5;
					if (enemyData.Metadata.PocketSFX == "default")
					{
						val6.pocketSFX = FastResourcesManager.EnemyDropDefaultSound;
					}
					else if (FastResourcesManager.CustomAudioClips.TryGetValue(enemyData.Metadata.PocketSFX, out value5))
					{
						val6.pocketSFX = value5;
					}
					else
					{
						val6.pocketSFX = null;
					}
					Items.RegisterItem(val6);
					Items.RegisterScrap(val6, 0, (LevelTypes)1);
					Enemies2Props.Add(enemyName, val5);
					Plugin.logger.LogInfo((object)("Registered NetworkPrefab '" + ((Object)val5).name + "'/'" + ((Object)val2).name + "' (" + val6.itemName + ")"));
				}
			}
		}
	}
	[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 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(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "..", "configs", "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");
		}

		private static void LoadCustomSounds()
		{
			if (!Directory.Exists(CustomSoundsFolder))
			{
				Directory.CreateDirectory(CustomSoundsFolder);
				Plugin.logger.LogInfo((object)"CustomSFX folder didn't exist, created one.");
			}
			string[] files = Directory.GetFiles(CustomSoundsFolder, "*.ogg", SearchOption.TopDirectoryOnly);
			string[] array = files;
			checked
			{
				foreach (string path in array)
				{
					string soundName = Path.GetFileNameWithoutExtension(path);
					if (CustomAudioClips.ContainsKey(soundName))
					{
						soundName += CustomAudioClips.Keys.Where((string n) => n == soundName).Count();
					}
					AudioClip val = AudioClip.Create("EM_CSFX_" + soundName, 88200, 1, 44100, false);
					FileStream fileStream = new FileStream(path, FileMode.Open);
					float[] array2 = new float[(int)unchecked(fileStream.Length / 4)];
					for (int j = 0; j < fileStream.Length; j += 4)
					{
						Span<byte> span = stackalloc byte[4];
						fileStream.Read(span);
						array2[unchecked(j / 4)] = BitConverter.ToSingle(span);
					}
					fileStream.Dispose();
					val.SetData(new ReadOnlySpan<float>(array2).ToArray(), 0);
					CustomAudioClips.Add(soundName, val);
				}
			}
		}
	}
	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);
			}
		}

		public static Vector3 ToUnityVec(this Vector3 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 Vector3 ToSystemVec(this 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 Vector3(v.x, v.y, v.z);
		}
	}
}
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)
			{
				string text = ((!LocalConfig.Singleton.synchronizeRanks.Value) ? (Synchronizable<SyncedConfig>.Default.EnemiesData[__instance.enemyType.enemyName].Rank ?? "?") : (Synchronizable<SyncedConfig>.Instance.EnemiesData[__instance.enemyType.enemyName].Rank ?? "?"));
				ScanNodeProperties componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<ScanNodeProperties>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.subText = "Rank " + text;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		private static void KillEnemy(EnemyAI __instance, bool destroy)
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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 (!__instance.isEnemyDead)
			{
				__instance.isEnemyDead = true;
			}
			if (!Synchronizable<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)
			{
				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);
			}
			((Component)__instance).transform.position = new Vector3(-10000f, -10000f, -10000f);
			__instance.SyncPositionToClients();
			Plugin.logger.LogDebug((object)"Mob should now be grabbable for all users.");
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManager_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void Start(GameNetworkManager __instance)
		{
			EnemyAI[] array = Resources.FindObjectsOfTypeAll<EnemyAI>();
			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 (!Synchronizable<SyncedConfig>.Instance.EnemiesData.ContainsKey(val.enemyType.enemyName))
				{
					EnemiesDataManager.RegisterEnemy(val.enemyType.enemyName, new EnemyData());
					Plugin.logger.LogInfo((object)("Mob was not registered. Registered it with name '" + val.enemyType.enemyName + "'"));
				}
			}
			EnemiesDataManager.SaveEnemiesData();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
		}

		[HarmonyPostfix]
		[HarmonyPatch("StartDisconnect")]
		public static void StartDisconnect()
		{
			Synchronizable<SyncedConfig>.RevertSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch("SaveItemsInShip")]
		public static void SaveItemsInShip(GameNetworkManager __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			Bounds bounds = StartOfRound.Instance.shipBounds.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			bounds = StartOfRound.Instance.shipBounds.bounds;
			Physics.OverlapBox(center, ((Bounds)(ref bounds)).size / 2f, ((Component)StartOfRound.Instance.shipBounds).transform.rotation, 6, (QueryTriggerInteraction)2);
			for (int i = 0; i < array.Length && i <= StartOfRound.Instance.maxShipItemCapacity; i = checked(i + 1))
			{
				GrabbableObject val = array[i];
				Plugin.logger.LogInfo((object)("SAVE CHECKER: Checking object " + val.itemProperties.itemName + "..."));
				if (StartOfRound.Instance.allItemsList.itemsList.Contains(val.itemProperties) && !val.deactivated)
				{
					if ((Object)(object)val.itemProperties.spawnPrefab == (Object)null)
					{
						Plugin.logger.LogError((object)("SAVE CHECKER: Object " + val.itemProperties.itemName + " didn't have a spawn prefab."));
						continue;
					}
					if (val.itemUsedUp)
					{
						Plugin.logger.LogError((object)("SAVE CHECKER: Object " + val.itemProperties.itemName + " didn't save because it was used up."));
						continue;
					}
					if (val.itemProperties.isScrap)
					{
						Plugin.logger.LogInfo((object)$"SAVE CHECKER: Saving object {val.itemProperties.itemName} scrap value: ${val.scrapValue}");
					}
					Plugin.logger.LogInfo((object)("SAVE CHECKER: Saving object " + val.itemProperties.itemName));
				}
				else
				{
					Plugin.logger.LogInfo((object)$"SAVE CHECKER: Not saving {val.itemProperties.itemName}. Deactivated: {val.deactivated} - Registered correctly: {StartOfRound.Instance.allItemsList.itemsList.Contains(val.itemProperties)}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	public class MaskedPlayerEnemy_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "KillEnemyServerRpc")]
		private static void KillEnemyServerRpc(MaskedPlayerEnemy __instance, bool destroy)
		{
			Plugin.logger.LogInfo((object)"Hey. Spawn a mimic mask. now.");
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	public class MenuManager_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuManager), "Start")]
		private static void Start(MenuManager __instance)
		{
			//IL_007d: 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.3.9</size>";
			((Component)__instance.versionNumberText).gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(500f, 50f);
			EnemyAI[] array = Resources.FindObjectsOfTypeAll<EnemyAI>();
			Plugin.logger.LogInfo((object)$"{array.Length} enemies to patch.");
			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 (!Synchronizable<SyncedConfig>.Instance.EnemiesData.ContainsKey(val.enemyType.enemyName))
				{
					EnemiesDataManager.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 + "'"));
				}
			}
			EnemiesDataManager.SaveEnemiesData();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
			Plugin.logger.LogInfo((object)"All enemies have been patched correctly.");
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerB_Patches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayerPrefabs()
		{
			EnemyAI[] array = Resources.FindObjectsOfTypeAll<EnemyAI>();
			Plugin.logger.LogInfo((object)$"Double checking {array.Length} enemies. The list may have changed.");
			EnemyAI[] array2 = array;
			foreach (EnemyAI val in array2)
			{
				if (!Synchronizable<SyncedConfig>.Instance.EnemiesData.ContainsKey(val.enemyType.enemyName))
				{
					EnemiesDataManager.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 + "'"));
				}
			}
			EnemiesDataManager.SaveEnemiesData();
			EnemiesDataManager.EnsureEnemy2PropPrefabs();
		}

		[HarmonyPostfix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (Synchronizable<SyncedConfig>.IsHost)
			{
				CustomMessagingManager messagingManager = Synchronizable<SyncedConfig>.MessagingManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = SyncedConfig.OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messagingManager.RegisterNamedMessageHandler("EnhancedMonsters_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				Synchronizable<SyncedConfig>.Synced = true;
				return;
			}
			Synchronizable<SyncedConfig>.Synced = false;
			CustomMessagingManager messagingManager2 = Synchronizable<SyncedConfig>.MessagingManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = SyncedConfig.OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messagingManager2.RegisterNamedMessageHandler("EnhancedMonsters_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			SyncedConfig.RequestSync();
		}
	}
}
namespace EnhancedMonsters.Monobehaviours
{
	public class EnemyScrap : GrabbableObject
	{
		public EnemyType enemyType;

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

		private const string SpiderSafeTag = "ShowArachnophobeMesh";

		public Animator EnemyAnimator { get; private set; }

		public ScanNodeProperties ScanNode { get; private set; }

		public GameObject EnemyGameObject { get; set; }

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

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

		public Dictionary<string, bool> AdditionalClientSettings { get; } = new Dictionary<string, bool>();


		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));
			}
			if (enemyType.enemyName == "Bunker Spider")
			{
				AdditionalClientSettings.TryAdd("ShowArachnophobeMesh", value: false);
			}
		}

		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 = Synchronizable<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 ? Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyType.enemyName] : Synchronizable<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 !"));
			}
			if (enemyType.enemyName == "Bunker Spider")
			{
				ToggleArachnophobeMesh(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
			}
		}

		public void FixedUpdate()
		{
			if (enemyType.enemyName == "Bunker Spider")
			{
				if (!AdditionalClientSettings.TryGetValue("ShowArachnophobeMesh", out var value))
				{
					AdditionalClientSettings.Add("ShowArachnophobeMesh", value: false);
				}
				if (value != IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode)
				{
					ToggleArachnophobeMesh(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
				}
			}
		}

		public override void PlayDropSFX()
		{
			((GrabbableObject)this).PlayDropSFX();
			if (enemyType.enemyName == "Bunker Spider")
			{
				ToggleArachnophobeMesh(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
			}
		}

		public override void GrabItem()
		{
			((GrabbableObject)this).GrabItem();
			if (enemyType.enemyName == "Bunker Spider")
			{
				ToggleArachnophobeMesh(IngamePlayerSettings.Instance.unsavedSettings.spiderSafeMode);
			}
		}

		public void ToggleArachnophobeMesh(bool newStatus)
		{
			Plugin.logger.LogInfo((object)"Trying to update the Spider mesh to match arachnophobia settings...");
			MeshRenderer component = ((Component)((Component)this).transform.GetChild(0).Find("MeshContainer").Find("AnimContainer")
				.Find("Armature")
				.Find("Abdomen")
				.Find("SpiderText")).GetComponent<MeshRenderer>();
			SkinnedMeshRenderer component2 = ((Component)((Component)this).transform.GetChild(0).Find("MeshContainer").Find("MeshRenderer")).GetComponent<SkinnedMeshRenderer>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2))
			{
				Plugin.logger.LogError((object)"This Spider mesh doesn't have a normal mesh or an arachnophobe mesh.");
				return;
			}
			AdditionalClientSettings["ShowArachnophobeMesh"] = newStatus;
			((Renderer)component).enabled = newStatus;
			((Renderer)component2).enabled = !newStatus;
			Plugin.logger.LogInfo((object)"The spider mesh have been updated to match player Arachnophobia settings !");
		}

		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 ? Synchronizable<SyncedConfig>.Instance.EnemiesData[enemyType.enemyName] : Synchronizable<SyncedConfig>.Default.EnemiesData[enemyType.enemyName]);
			ScanNode.subText = $"Rank: {enemyData.Rank}\nValue: {value}";
		}

		public IEnumerator DisableAnimatorOnAnimationEnd()
		{
			AnimatorClipInfo[] currentClip = EnemyAnimator.GetCurrentAnimatorClipInfo(0);
			if (currentClip.Length >= 1)
			{
				float deathAnimDuration = ((AnimatorClipInfo)(ref currentClip[0])).clip.length;
				AnimatorStateInfo currentAnimatorStateInfo = EnemyAnimator.GetCurrentAnimatorStateInfo(0);
				float deathAnimProgress = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
				while (deathAnimProgress < deathAnimDuration)
				{
					yield return (object)new WaitForEndOfFrame();
				}
				((Behaviour)EnemyAnimator).enabled = false;
			}
		}

		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 internal override string __getTypeName()
		{
			return "EnemyScrap";
		}
	}
}
namespace EnhancedMonsters.Config
{
	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_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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0104: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			LocalConfig config2 = config;
			LethalConfigManager.SetModDescription("Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements.");
			ConfigEntry<bool> synchronizeRanks = config2.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);
			BoolCheckBoxConfigItem val4 = new BoolCheckBoxConfigItem(config2.dungeonSoundExchange, new BoolCheckBoxOptions
			{
				Name = "Dungeon Sound Exchange",
				Section = "Entrance Improvements",
				RequiresRestart = false
			});
			ConfigEntry<int> dungeonSoundExchangeVolume = config2.dungeonSoundExchangeVolume;
			IntSliderOptions val5 = new IntSliderOptions
			{
				Name = "Dungeon Sound Exchange Volume",
				Section = "Entrance Improvements"
			};
			((BaseRangeOptions<int>)val5).Min = 0;
			((BaseRangeOptions<int>)val5).Max = 100;
			((BaseOptions)val5).RequiresRestart = false;
			((BaseOptions)val5).CanModifyCallback = (CanModifyDelegate)(() => CanModifyResult.op_Implicit(config2.dungeonSoundExchange.Value));
			IntSliderConfigItem val6 = new IntSliderConfigItem(dungeonSoundExchangeVolume, val5);
			object obj2 = <>c.<>9__3_0;
			if (obj2 == null)
			{
				GenericButtonHandler val7 = delegate
				{
					GUIUtility.systemCopyBuffer = EnemiesDataManager.EnemiesDataFile;
				};
				<>c.<>9__3_0 = val7;
				obj2 = (object)val7;
			}
			GenericButtonConfigItem val8 = 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)val8);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val4);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val6);
		}
	}
	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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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 lsDungeonPrevQltComp");
			Plugin.logger.LogInfo((object)"Registering lsDungeonPrevComponent");
			Plugin.logger.LogInfo((object)"Registering lsDungeonSndVolComponent");
			SliderComponent lsDungeonSndVolComponent = new SliderComponent
			{
				Enabled = false,
				Text = "[UNAVAILABLE] Dungeon Sound Exchange Volume",
				Value = 100f,
				MinValue = 0f,
				MaxValue = 100f,
				ShowValue = true,
				WholeNumbers = true,
				OnValueChanged = delegate(SliderComponent comp, float value)
				{
					config2.dungeonSoundExchangeVolume.Value = checked((int)value);
				},
				OnInitialize = delegate(SliderComponent comp)
				{
					comp.Value = config2.dungeonSoundExchangeVolume.Value;
				}
			};
			Plugin.logger.LogInfo((object)"Registering lsDungeonSndComponent");
			ToggleComponent val2 = new ToggleComponent
			{
				Enabled = false,
				Text = "[UNAVAILABLE] Dungeon Sound Exchange",
				Value = true,
				OnValueChanged = delegate(ToggleComponent comp, bool value)
				{
					config2.dungeonSoundExchange.Value = value;
					lsDungeonSndVolComponent.Enabled = value;
				},
				OnInitialize = delegate(ToggleComponent comp)
				{
					comp.Value = config2.dungeonSoundExchange.Value;
					lsDungeonSndVolComponent.Enabled = config2.dungeonSoundExchange.Value;
				}
			};
			Plugin.logger.LogInfo((object)"Registering lsAccessEnemiesDataFile");
			ButtonComponent val3 = 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 val4 = new ModSettingsConfig();
			val4.Id = "com.velddev.enhancedmonsters";
			val4.Name = "Enhanced Monsters";
			val4.Version = "1.3.9";
			val4.Description = "Enhanced Monsters aims at enhancing experience towards monsters, but also has various QOL improvements.";
			val4.MenuComponents = (MenuComponent[])(object)new MenuComponent[2]
			{
				(MenuComponent)val,
				(MenuComponent)val3
			};
			ModMenu.RegisterMod(val4);
			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.";

		internal readonly bool SeamlessDungeonExists;

		public readonly ConfigEntry<bool> synchronizeRanks;

		public readonly ConfigEntry<bool> dungeonSoundExchange;

		public readonly ConfigEntry<int> dungeonSoundExchangeVolume;

		public static LocalConfig Singleton { get; private set; }

		public LocalConfig(ConfigFile cfg)
		{
			Singleton = this;
			SeamlessDungeonExists = Chainloader.PluginInfos.ContainsKey("tsundrella.seamlessdungeon");
			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.]");
			dungeonSoundExchange = cfg.Bind<bool>("Entrance Improvements", "Unimplemented - Dungeon Sound Exchange", true, "Unimplemented - Wether to enable or not sound exchange between interior and exterior of the dungeon, next to entrance and fire exits. Disabling it can enhance performance on weakest configurations.");
			dungeonSoundExchangeVolume = cfg.Bind<int>("Entrance Improvements", "Unimplemented - Dungeon Sound Exchange Volume", 70, "Unimplemented - Volume level of sounds emitted from the interior/exterior when player is on the other side of the door.");
			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.");
		}
	}
	[Serializable]
	public class SyncedConfig : Synchronizable<SyncedConfig>
	{
		public Dictionary<string, EnemyData> EnemiesData;

		[NonSerialized]
		public ConfigFile BepInConfigs;

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

		public static void BroadcastSync()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!Synchronizable<SyncedConfig>.IsHost)
			{
				return;
			}
			Plugin.logger.LogDebug((object)"Host is broadcasting its config.");
			byte[] array = Synchronizable<SyncedConfig>.Serialize(Synchronizable<SyncedConfig>.Instance);
			int num = array.Length;
			int num2 = checked(FastBufferWriter.GetWriteSize<byte>(array, -1, 0) + Synchronizable<SyncedConfig>.IntSize);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num2, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				Synchronizable<SyncedConfig>.MessagingManager.SendNamedMessageToAll("EnhancedMonster_OnReceiveConfigSync", val, (NetworkDelivery)4);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"The config sync broadcast lamentably failed lmao; here's the error: {arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void RequestSync()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!Synchronizable<SyncedConfig>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(Synchronizable<SyncedConfig>.IntSize, (Allocator)2, -1);
			try
			{
				Synchronizable<SyncedConfig>.MessagingManager.SendNamedMessage("EnhancedMonsters_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
				Plugin.logger.LogInfo((object)"Asking host for their EnemyData config");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!Synchronizable<SyncedConfig>.IsHost)
			{
				return;
			}
			Plugin.logger.LogDebug((object)$"Config sync request received from client {clientId}");
			byte[] array = Synchronizable<SyncedConfig>.Serialize(Synchronizable<SyncedConfig>.Instance);
			int num = array.Length;
			int writeSize = FastBufferWriter.GetWriteSize<byte>(array, -1, 0);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(checked(writeSize + Synchronizable<SyncedConfig>.IntSize), (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				Synchronizable<SyncedConfig>.MessagingManager.SendNamedMessage("EnhancedMonsters_OnReceiveConfigSync", clientId, val, (NetworkDelivery)4);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Coudln't sync configs between clients. Error: {arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(Synchronizable<SyncedConfig>.IntSize))
			{
				Plugin.logger.LogError((object)"Config sync error: could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.logger.LogError((object)$"Config sync error: Host could not sync. Error: The chunk of the buffer to read is larger than the remaining bytes chunk. {num} bytes to read, {checked(((FastBufferReader)(ref reader)).Length - ((FastBufferReader)(ref reader)).Position)} remaining bytes");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			Synchronizable<SyncedConfig>.SyncInstance(data);
			Plugin.logger.LogInfo((object)"Successfully synced config with host");
		}
	}
	[Serializable]
	public class Synchronizable<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessagingManager => NetworkManager.Singleton.CustomMessagingManager;

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

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

		public static T Default { get; set; }

		public static T Instance { get; set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = Deserialize(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] Serialize(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Error while serializing Config instance: {arg}");
				return null;
			}
		}

		public static T Deserialize(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Couldn't deserialize Config instance: {arg}");
				return default(T);
			}
		}
	}
}
namespace EnhancedMonsters.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}