Decompiled source of INTEGER EarlyAccess v1.0.31

Plugins/INTEGER II/Custom/ExtraEnemyCustomization/ExtraEnemyCustomization.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AIGraph;
using AK;
using Agents;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CellMenu;
using CullingSystem;
using EEC.API;
using EEC.Configs;
using EEC.Configs.Customizations;
using EEC.CustomAbilities.Bleed;
using EEC.CustomAbilities.Bleed.Handlers;
using EEC.CustomAbilities.Bleed.Inject;
using EEC.CustomAbilities.DrainStamina;
using EEC.CustomAbilities.EMP;
using EEC.CustomAbilities.EMP.Handlers;
using EEC.CustomAbilities.EMP.Inject;
using EEC.CustomAbilities.Explosion;
using EEC.CustomAbilities.Explosion.Handlers;
using EEC.CustomSettings.CustomProjectiles;
using EEC.CustomSettings.CustomScoutWaves;
using EEC.CustomSettings.CustomTentacles;
using EEC.EnemyCustomizations;
using EEC.EnemyCustomizations.Abilities;
using EEC.EnemyCustomizations.Abilities.Handlers;
using EEC.EnemyCustomizations.Abilities.Inject;
using EEC.EnemyCustomizations.Detections;
using EEC.EnemyCustomizations.EnemyAbilities;
using EEC.EnemyCustomizations.EnemyAbilities.Abilities;
using EEC.EnemyCustomizations.EnemyAbilities.Events;
using EEC.EnemyCustomizations.EnemyAbilities.Handlers;
using EEC.EnemyCustomizations.Models;
using EEC.EnemyCustomizations.Models.Handlers;
using EEC.EnemyCustomizations.Properties;
using EEC.EnemyCustomizations.Shared;
using EEC.EnemyCustomizations.Shared.Handlers;
using EEC.EnemyCustomizations.Shooters;
using EEC.EnemyCustomizations.Shooters.Handlers;
using EEC.EnemyCustomizations.Strikers;
using EEC.Events;
using EEC.Managers;
using EEC.Managers.Assets;
using EEC.Managers.Properties;
using EEC.Networking;
using EEC.Networking.Events;
using EEC.Networking.Replicators;
using EEC.Patches.Handlers;
using EEC.Utils;
using EEC.Utils.Integrations;
using EEC.Utils.Json;
using EEC.Utils.Json.Converters;
using EEC.Utils.Json.Elements;
using EEC.Utils.Unity;
using Enemies;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.InteropTypes.Fields;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Player;
using SNetwork;
using SemanticVersioning;
using StateMachines;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ExtraEnemyCustomization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: AssemblyInformationalVersion("1.6.0")]
[assembly: AssemblyProduct("ExtraEnemyCustomization")]
[assembly: AssemblyTitle("ExtraEnemyCustomization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.0.0")]
[module: UnverifiableCode]
namespace EEC
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	internal sealed class CallConstructorOnLoadAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
	internal sealed class InjectToIl2CppAttribute : Attribute
	{
	}
	public static class Configuration
	{
		public const string SECTION_USER = "1. User-End";

		public const string SECTION_RUNDEVS = "2. Rundown Developer";

		public const string SECTION_LOGGING = "3. Logging";

		public const string SECTION_DEV = "4. DEBUG";

		public const int CONFIG_VERSION = 1;

		private static ConfigEntry<bool> _showMarkerText;

		private static ConfigEntry<bool> _showMarkerDistance;

		private static ConfigEntry<bool> _showExplosionEffect;

		private static ConfigEntry<ShitpostType> _shitpostType;

		private static ConfigEntry<bool> _useLiveEdit;

		private static ConfigEntry<bool> _linkMTFOHotReload;

		private static ConfigEntry<bool> _useDebugLog;

		private static ConfigEntry<bool> _useVerboseLog;

		private static ConfigEntry<AssetCacheManager.OutputType> _assetCacheBehaviour;

		private static ConfigEntry<bool> _dumpConfig;

		private static ConfigEntry<bool> _profiler;

		private static ConfigFile _currentContext;

		public static bool ShowMarkerText { get; private set; }

		public static bool ShowMarkerDistance { get; private set; }

		public static bool ShowExplosionEffect { get; private set; }

		public static ShitpostType ShitpostType { get; private set; }

		public static bool UseLiveEdit { get; private set; }

		public static bool LinkMTFOHotReload { get; private set; }

		public static bool UseDebugLog { get; private set; }

		public static bool UseVerboseLog { get; private set; }

		public static AssetCacheManager.OutputType AssetCacheBehaviour { get; private set; }

		public static bool DumpConfig { get; private set; }

		public static bool Profiler { get; private set; }

		public static bool CanShitpostOf(ShitpostType type)
		{
			switch (ShitpostType)
			{
			case ShitpostType.ForceOff:
				return false;
			case ShitpostType.Enable:
			{
				DateTime now = DateTime.Now;
				if (now.Month == 4)
				{
					return now.Day == 1;
				}
				return false;
			}
			default:
				return ShitpostType.HasFlag(type);
			}
		}

		public static void CreateAndBindAll()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "EEC.cfg");
			ConfigFile context = new ConfigFile(text, true);
			if (BindConfigVersion(context).Value < 1)
			{
				File.Delete(text);
				context = new ConfigFile(text, true);
				BindConfigVersion(context);
			}
			BindAll(context);
		}

		public static void BindAll(ConfigFile context)
		{
			_currentContext = context;
			_showMarkerText = BindUserConfig("Marker Text", "Display Enemy Marker Texts? (if set by rundown devs)", defaultValue: true);
			_showMarkerDistance = BindUserConfig("Marker Distance", "Display Enemy Marker Distance? (if set by rundown devs)", defaultValue: true);
			_showExplosionEffect = BindUserConfig("Explosion Flash", "(Accessibility) Display Light flash effect for explosion abilities?", defaultValue: true);
			_shitpostType = BindUserConfig("Shitposting", "Shitpost mode use comma to enable multiple stuffs", ShitpostType.ForceOff);
			ShowMarkerText = _showMarkerText.Value;
			ShowMarkerDistance = _showMarkerDistance.Value;
			ShowExplosionEffect = _showExplosionEffect.Value;
			ShitpostType = _shitpostType.Value;
			_useLiveEdit = BindRdwDevConfig("Live Edit", "Reload Config when they are edited while in-game", defaultValue: false);
			_linkMTFOHotReload = BindRdwDevConfig("Reload on MTFO HotReload", "Reload Configs when MTFO's HotReload button has pressed?", defaultValue: true);
			UseLiveEdit = _useLiveEdit.Value;
			LinkMTFOHotReload = _linkMTFOHotReload.Value;
			_useDebugLog = BindLoggingConfig("UseDevMessage", "Using Dev Message for Debugging your config?", defaultValue: false);
			_useVerboseLog = BindLoggingConfig("Verbose", "Using Much more detailed Message for Debugging?", defaultValue: false);
			_assetCacheBehaviour = BindLoggingConfig("Cached Asset Result Output", "How does your cached material/texture result be returned?", AssetCacheManager.OutputType.None);
			UseDebugLog = _useDebugLog.Value;
			UseVerboseLog = _useVerboseLog.Value;
			AssetCacheBehaviour = _assetCacheBehaviour.Value;
			_dumpConfig = BindDevConfig("DumpConfig", "Dump Empty Config file?", defaultValue: false);
			_profiler = BindDevConfig("Profiler", "Show Profiler Info for Spawned Event", defaultValue: false);
			DumpConfig = _dumpConfig.Value;
			Profiler = _profiler.Value;
		}

		private static ConfigEntry<int> BindConfigVersion(ConfigFile context)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			return context.Bind<int>(new ConfigDefinition("Version", "Config Version"), 1, (ConfigDescription)null);
		}

		private static ConfigEntry<T> BindUserConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "1. User-End", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindRdwDevConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "2. Rundown Developer", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindLoggingConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "3. Logging", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindDevConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "4. DEBUG", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindItem<T>(ConfigFile context, string section, string name, string description, T defaultValue)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_001b: Expected O, but got Unknown
			return context.Bind<T>(new ConfigDefinition(section, name), defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[BepInPlugin("GTFO.EECustomization", "EECustom", "1.7.7")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		public static Harmony HarmonyInstance { get; private set; }

		public static string BasePath { get; private set; }

		public override void Load()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Configuration.CreateAndBindAll();
			Logger.Initialize();
			InjectAllIl2CppType();
			CallAllAutoConstructor();
			BasePath = Path.Combine(MTFOUtil.CustomPath, "ExtraEnemyCustomization");
			HarmonyInstance = new Harmony("EEC.Harmony");
			HarmonyInstance.PatchAll();
			NetworkManager.Initialize();
			ConfigManager.Initialize();
			if (Configuration.DumpConfig)
			{
				ConfigManager.DumpDefault();
			}
			AssetEvents.AllAssetLoaded += AllAssetLoaded;
			AssetCacheManager.OutputMethod = Configuration.AssetCacheBehaviour;
		}

		private void AllAssetLoaded()
		{
			SpriteManager.Initialize();
			AssetCacheManager.AssetLoaded();
			ConfigManager.FireAssetLoaded();
			ConfigManager.FirePrefabBuildEventAll(rebuildPrefabs: false);
		}

		public override bool Unload()
		{
			UninjectAllIl2CppType();
			HarmonyInstance.UnpatchSelf();
			ConfigManager.UnloadAllConfig(doClear: true);
			return ((BasePlugin)this).Unload();
		}

		private void InjectAllIl2CppType()
		{
			Logger.Debug("Injecting IL2CPP Types");
			IEnumerable<Type> allHandlers = GetAllHandlers();
			Logger.Debug($" - Count: {allHandlers.Count()}");
			foreach (Type item in allHandlers)
			{
				if (!ClassInjector.IsTypeRegisteredInIl2Cpp(item))
				{
					ClassInjector.RegisterTypeInIl2Cpp(item);
				}
			}
		}

		private void CallAllAutoConstructor()
		{
			Logger.Debug("Calling Necessary Static .ctors");
			IEnumerable<Type> allAutoConstructor = GetAllAutoConstructor();
			Logger.Debug($" - Count: {allAutoConstructor.Count()}");
			foreach (Type item in allAutoConstructor)
			{
				Logger.Debug("calling ctor of: " + item.Name);
				RuntimeHelpers.RunClassConstructor(item.TypeHandle);
			}
		}

		private void UninjectAllIl2CppType()
		{
			Logger.Debug("Uninjecting IL2CPP Types");
			IEnumerable<Type> allHandlers = GetAllHandlers();
			Logger.Debug($" - Count: {allHandlers.Count()}");
			foreach (Type item in allHandlers)
			{
				ClassInjector.IsTypeRegisteredInIl2Cpp(item);
			}
		}

		private IEnumerable<Type> GetAllAutoConstructor()
		{
			return from type in ((object)this).GetType().Assembly.GetTypes()
				where type != null && Attribute.IsDefined(type, typeof(CallConstructorOnLoadAttribute))
				select type;
		}

		private IEnumerable<Type> GetAllHandlers()
		{
			return from type in ((object)this).GetType().Assembly.GetTypes()
				where type != null && Attribute.IsDefined(type, typeof(InjectToIl2CppAttribute))
				select type;
		}
	}
	public static class AgentExtension
	{
		public static bool TryCastToEnemyAgent(this Agent agent, out EnemyAgent enemyAgent)
		{
			return TryCast<EnemyAgent>(agent, (AgentType)1, out enemyAgent);
		}

		public static bool TryCastToPlayerAgent(this Agent agent, out PlayerAgent playerAgent)
		{
			return TryCast<PlayerAgent>(agent, (AgentType)0, out playerAgent);
		}

		private static bool TryCast<T>(Agent agent, AgentType type, out T result) where T : Agent
		{
			//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)
			if (!((Object)(object)agent == (Object)null) && !((Il2CppObjectBase)agent).WasCollected && agent.Type == type)
			{
				T val = ((Il2CppObjectBase)agent).TryCast<T>();
				if (!((Object)(object)val == (Object)null))
				{
					result = val;
					return true;
				}
			}
			result = default(T);
			return false;
		}
	}
	public static class EasingExtension
	{
		public static float Evaluate(this eEasingType easeType, float progress, bool backward = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Easing.GetEasingValue(easeType, progress, backward);
		}

		public static Func<float, float, float, float, float> GetEaseFunction(this eEasingType easeType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected I4, but got Unknown
			return (easeType - 1) switch
			{
				0 => Easing.EaseInQuad, 
				1 => Easing.EaseOutQuad, 
				2 => Easing.EaseInOutQuad, 
				3 => Easing.EaseInCubic, 
				4 => Easing.EaseOutCubic, 
				5 => Easing.EaseInOutCubic, 
				6 => Easing.EaseInQuart, 
				7 => Easing.EaseOutQuart, 
				8 => Easing.EaseInOutQuart, 
				9 => Easing.EaseInQuint, 
				10 => Easing.EaseOutQuint, 
				11 => Easing.EaseInOutQuint, 
				12 => Easing.EaseInSine, 
				13 => Easing.EaseOutSine, 
				14 => Easing.EaseInOutSine, 
				15 => Easing.EaseInExpo, 
				16 => Easing.EaseOutExpo, 
				17 => Easing.EaseInOutExpo, 
				18 => Easing.EaseInCirc, 
				19 => Easing.EaseOutCirc, 
				20 => Easing.EaseInOutCirc, 
				_ => Easing.LinearTween, 
			};
		}
	}
	public static class EnemyAgentExtension
	{
		public static void AddOnDeadOnce(this EnemyAgent agent, Action onDead)
		{
			bool called = false;
			agent.OnDeadCallback += Action.op_Implicit((Action)delegate
			{
				if (!called)
				{
					onDead?.Invoke();
					called = true;
				}
			});
		}

		public static T RegisterOrGetProperty<T>(this EnemyAgent agent) where T : class, new()
		{
			return EnemyProperty<T>.RegisterOrGet(agent);
		}

		public static bool TryGetProperty<T>(this EnemyAgent agent, out T property) where T : class, new()
		{
			return EnemyProperty<T>.TryGet(agent, out property);
		}

		public static bool TryGetSpawnData(this EnemyAgent agent, out pEnemySpawnData spawnData)
		{
			return EnemySpawnDataManager.TryGet(((Agent)agent).GlobalID, out spawnData);
		}

		public static bool TryGetEnemyGroup(this EnemyAgent agent, out EnemyGroup group)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (!agent.TryGetSpawnData(out var spawnData))
			{
				group = null;
				return false;
			}
			if (spawnData.groupReplicatorKey == 0)
			{
				group = null;
				return false;
			}
			IReplicator val = default(IReplicator);
			if (SNet_Replication.TryGetReplicator(spawnData.groupReplicatorKey, ref val))
			{
				group = null;
				return false;
			}
			if (val.ReplicatorSupplier == null)
			{
				group = null;
				return false;
			}
			group = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<EnemyGroup>();
			return (Object)(object)group != (Object)null;
		}

		public static AIG_CourseNode GetSpawnedNode(this EnemyAgent agent)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			pEnemySpawnData spawnData = ((SNet_DynamicReplicator<pEnemySpawnData>)(object)((Il2CppObjectBase)agent.Sync.Replicator).Cast<EnemyReplicator>()).GetSpawnData();
			AIG_CourseNode result = default(AIG_CourseNode);
			if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref result))
			{
				return null;
			}
			return result;
		}
	}
	public static class EnemyDataBlockExtension
	{
		public static bool TryGetBehaviourBlock(this EnemyDataBlock data, out EnemyBehaviorDataBlock behaviour)
		{
			if (data == null)
			{
				behaviour = null;
				return false;
			}
			behaviour = GameDataBlockBase<EnemyBehaviorDataBlock>.GetBlock(data.BehaviorDataId);
			return behaviour != null;
		}

		public static bool TryGetBalancingBlock(this EnemyDataBlock data, out EnemyBalancingDataBlock balancing)
		{
			if (data == null)
			{
				balancing = null;
				return false;
			}
			balancing = GameDataBlockBase<EnemyBalancingDataBlock>.GetBlock(data.BalancingDataId);
			return balancing != null;
		}
	}
	public static class GameObjectExtension
	{
		public static bool TryGetComp<T>(this GameObject obj, out T component)
		{
			component = obj.GetComponent<T>();
			return component != null;
		}

		public static T AddOrGetComponent<T>(this GameObject obj) where T : Component
		{
			if (!obj.TryGetComp<T>(out var component))
			{
				return obj.AddComponent<T>();
			}
			return component;
		}

		public static GameObject FindChild(this GameObject obj, string name, bool includeInactive = false)
		{
			foreach (Transform componentsInChild in obj.GetComponentsInChildren<Transform>(includeInactive))
			{
				if (!(((Object)((Component)componentsInChild).gameObject).name != name))
				{
					return ((Component)componentsInChild).gameObject;
				}
			}
			return null;
		}

		public static GameObject RegexFindChild(this GameObject obj, Regex rx, bool includeInactive = false)
		{
			foreach (Transform componentsInChild in obj.GetComponentsInChildren<Transform>(includeInactive))
			{
				if (rx.IsMatch(((Object)componentsInChild).name))
				{
					return ((Component)componentsInChild).gameObject;
				}
			}
			return null;
		}

		public static GameObject Instantiate(this GameObject obj, Transform toParent, string name)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj2 = Object.Instantiate<GameObject>(obj);
			obj2.transform.parent = toParent;
			obj2.transform.localPosition = Vector3.zero;
			obj2.transform.localRotation = Quaternion.Euler(Vector3.zero);
			((Object)obj2).name = name;
			return obj2;
		}
	}
	public static class MonoBehaviourExtension
	{
		public static Coroutine StartCoroutine(this MonoBehaviour self, IEnumerator routine)
		{
			return self.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(routine));
		}
	}
	public static class ProjectileTargetingExtension
	{
		public static bool TryGetOwnerEnemyDataID(this ProjectileBase projectile, out uint id)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				id = 0u;
				return false;
			}
			return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
		}

		public static bool TryGetOwnerEnemyDataID(this ProjectileTargeting projectile, out uint id)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				id = 0u;
				return false;
			}
			return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
		}

		public static bool TryGetOwner(this ProjectileBase projectile, out EnemyAgent agent)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				agent = null;
				return false;
			}
			return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
		}

		public static bool TryGetOwner(this ProjectileTargeting projectile, out EnemyAgent agent)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				agent = null;
				return false;
			}
			return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
		}
	}
	public static class StringExtension
	{
		public static bool InvariantEquals(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.Equals(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantContains(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.Contains(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantStartsWith(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.StartsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantEndsWith(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.EndsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool EqualsAnyIgnoreCase(this string input, params string[] args)
		{
			return input.EqualsAny(ignoreCase: true, args);
		}

		public static bool EqualsAny(this string input, bool ignoreCase, params string[] args)
		{
			StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
			foreach (string value in args)
			{
				if (input.Equals(value, comparisonType))
				{
					return true;
				}
			}
			return false;
		}

		public static bool ContainsAnyIgnoreCase(this string input, params string[] args)
		{
			return input.ContainsAny(ignoreCase: true, args);
		}

		public static bool ContainsAny(this string input, bool ignoreCase, params string[] args)
		{
			StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
			foreach (string value in args)
			{
				if (input.Contains(value, comparisonType))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class Logger
	{
		public static ManualLogSource LogInstance { get; private set; }

		public static bool UsingDevMessage { get; private set; }

		public static bool UsingVerbose { get; private set; }

		public static bool DevLogAllowed => UsingDevMessage;

		public static bool VerboseLogAllowed
		{
			get
			{
				if (UsingDevMessage)
				{
					return UsingVerbose;
				}
				return false;
			}
		}

		internal static void Initialize()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			LogInstance = new ManualLogSource("EEC");
			Logger.Sources.Add((ILogSource)(object)LogInstance);
			UsingDevMessage = Configuration.UseDebugLog;
			UsingVerbose = Configuration.UseVerboseLog;
		}

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)4, (object)str);
			}
		}

		public static void Error(string format, params object[] args)
		{
			Error(string.Format(format, args));
		}

		public static void Error(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (UsingDevMessage)
			{
				ManualLogSource logInstance = LogInstance;
				if (logInstance != null)
				{
					logInstance.LogDebug((object)str);
				}
			}
		}

		public static void Verbose(string format, params object[] args)
		{
			Verbose(string.Format(format, args));
		}

		public static void Verbose(string str)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (!UsingDevMessage || !UsingVerbose)
			{
				return;
			}
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(10, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(str);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (Verbose)");
				}
				logInstance.LogDebug(val);
			}
		}

		[Conditional("DEBUG")]
		[Obsolete("Logger.Dev call will be removed in release mode!")]
		public static void Dev(string format, params object[] args)
		{
		}

		[Conditional("DEBUG")]
		[Obsolete("Logger.Dev call will be removed in release mode!")]
		public static void Dev(string str)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				LogLevel val = (LogLevel)8;
				LogLevel val2 = val;
				bool flag = default(bool);
				BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(6, 1, val, ref flag);
				if (flag)
				{
					val3.AppendLiteral("[DEV] ");
					val3.AppendFormatted<string>(str);
				}
				logInstance.Log(val2, val3);
			}
		}
	}
}
namespace EEC.Utils
{
	public static class EnemyAnimUtil
	{
		private static readonly Dictionary<EnemyAnimType, int[]> _animHashsLookup;

		private static bool _initialized;

		static EnemyAnimUtil()
		{
			_animHashsLookup = new Dictionary<EnemyAnimType, int[]>(Enum.GetValues(typeof(EnemyAnimType)).Length);
		}

		internal static void Initialize()
		{
			if (!_initialized)
			{
				CacheLookup();
				_initialized = true;
			}
		}

		private static void CacheLookup()
		{
			Type typeFromHandle = typeof(EnemyLocomotion);
			foreach (EnemyAnimType value in Enum.GetValues(typeof(EnemyAnimType)))
			{
				switch (value)
				{
				case EnemyAnimType.Heartbeats:
					_animHashsLookup.Add(value, Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)EnemyLocomotion.s_hashHearbeats));
					Logger.Verbose($"{value},  {string.Join(" / ", (IEnumerable<int>)EnemyLocomotion.s_hashHearbeats)}");
					continue;
				case EnemyAnimType.None:
					continue;
				}
				string text = "s_hash" + Enum.GetName(typeof(EnemyAnimType), value);
				PropertyInfo property = typeFromHandle.GetProperty(text, BindingFlags.Static | BindingFlags.Public);
				if (property == null)
				{
					Logger.Warning(text + " does not exist!");
				}
				else if (property.PropertyType == typeof(int))
				{
					_animHashsLookup.Add(value, new int[1] { (int)property.GetValue(null) });
					Logger.Verbose($"{value},  {property.GetValue(null)}");
				}
				else if (property.PropertyType == typeof(Il2CppStructArray<int>))
				{
					int[] array = Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)(Il2CppStructArray<int>)property.GetValue(null));
					_animHashsLookup.Add(value, array);
					Logger.Verbose($"{value},  {string.Join(" / ", array)}");
				}
				else
				{
					Logger.Error($"{value} is not a valid hash property!");
				}
			}
		}

		public static void DoAnimationLocal(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
		{
			if (!_initialized)
			{
				Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
			}
			else
			{
				if (type == EnemyAnimType.None)
				{
					return;
				}
				if (!_animHashsLookup.TryGetValue(type, out var value))
				{
					Logger.Error($"Cannot find AnimationHash with: {type}");
					return;
				}
				int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
				agent.Locomotion.m_animator.applyRootMotion = true;
				agent.Locomotion.m_animator.CrossFadeInFixedTime(value[num], crossfadeTime);
				if (pauseAI && ((AgentAI)agent.AI).m_navMeshAgent.isOnNavMesh)
				{
					((AgentAI)agent.AI).m_navMeshAgent.isStopped = true;
				}
			}
		}

		public static void DoAnimation(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
		{
			if (!_initialized)
			{
				Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
			}
			else if (type != 0)
			{
				if (!_animHashsLookup.TryGetValue(type, out var value))
				{
					Logger.Error($"Cannot find AnimationHash with: {type}");
					return;
				}
				int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
				NetworkManager.EnemyAnim.Send(new EnemyAnimEvent.Packet
				{
					enemyID = ((Agent)agent).GlobalID,
					crossfadeTime = crossfadeTime,
					pauseAI = pauseAI,
					animHash = value[num]
				});
			}
		}
	}
	public enum EnemyAnimType : byte
	{
		None,
		MoveOnGround,
		Forward,
		Right,
		ClimbLadder,
		GiveBirth,
		HitLights_Fwd,
		HitLights_Bwd,
		HitLights_Rt,
		HitLights_Lt,
		HitHeavys_Fwd,
		HitHeavys_Bwd,
		HitHeavys_Rt,
		HitHeavys_Lt,
		Screams,
		ScreamTurns,
		HibernationIn,
		Heartbeats,
		HibernationWakeups,
		HibernationWakeupTurns,
		AbilityFires,
		AbilityUse,
		AbilityUseOut,
		MeleeWalkSequences,
		MeleeSequences,
		Melee180Sequences,
		JumpStart,
		JumpLand
	}
	public static class EnemyProperty<T> where T : class, new()
	{
		private static readonly Dictionary<ushort, T> _properties;

		public static IEnumerable<T> Properties => _properties.Values;

		static EnemyProperty()
		{
			_properties = new Dictionary<ushort, T>();
			EnemyEvents.Despawn += EnemyDespawn;
			LevelEvents.LevelCleanup += OnLevelCleanup;
		}

		private static void EnemyDespawn(EnemyAgent agent)
		{
			_properties.Remove(((Agent)agent).GlobalID);
		}

		private static void OnLevelCleanup()
		{
			_properties.Clear();
		}

		public static T RegisterOrGet(EnemyAgent agent)
		{
			T val = RegisterEnemy(agent);
			if (val != null)
			{
				return val;
			}
			return Get(agent);
		}

		public static T RegisterEnemy(EnemyAgent agent)
		{
			ushort globalID = ((Agent)agent).GlobalID;
			if (_properties.ContainsKey(globalID))
			{
				return null;
			}
			T val = new T();
			_properties.Add(globalID, val);
			return val;
		}

		public static T Get(EnemyAgent agent)
		{
			return Get(((Agent)agent).GlobalID);
		}

		public static T Get(ushort id)
		{
			if (_properties.ContainsKey(id))
			{
				return _properties[id];
			}
			return null;
		}

		public static bool TryGet(EnemyAgent agent, out T property)
		{
			return TryGet(((Agent)agent).GlobalID, out property);
		}

		public static bool TryGet(ushort id, out T property)
		{
			return _properties.TryGetValue(id, out property);
		}
	}
	[Obsolete("Will be moved to ExplosionManager")]
	public static class ExplosionUtil
	{
		public static void MakeExplosion(Vector3 position, float damage, float enemyMulti, float minRange, float maxRange)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			ExplosionData data = default(ExplosionData);
			data.position = position;
			data.damage = damage;
			data.enemyMulti = enemyMulti;
			data.minRange = minRange;
			data.maxRange = maxRange;
			data.lightColor = ExplosionManager.FlashColor;
			ExplosionManager.DoExplosion(data);
		}
	}
	public static class PlayerData
	{
		public static float MaxHealth { get; internal set; } = 25f;


		public static float MaxInfection { get; internal set; } = 1f;

	}
	public static class Rand
	{
		public const int InclusiveDoublePrecision = 10000;

		public const double InclusiveDoubleConversion = 0.0001;

		private static readonly Random _rand = new Random();

		public static Random CreateInstance()
		{
			return new Random(_rand.Next());
		}

		public static T ItemOf<T>(T[] array)
		{
			return array[IndexOf(array)];
		}

		public static int IndexOf(Array array)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				throw new ArgumentException("Array Length was zero!", "array");
			}
			return _rand.Next(0, array.Length);
		}

		public static int Index(int length)
		{
			return _rand.Next(0, length);
		}

		public static int Range(int min, int max)
		{
			return _rand.Next(min, max);
		}

		public static float Range(float min, float max)
		{
			return NextFloat() * (max - min) + min;
		}

		public static int RangeInclusive(int min, int max)
		{
			return _rand.Next(min, max + 1);
		}

		public static float RangeInclusive(float min, float max)
		{
			return NextFloatInclusive() * (max - min) + min;
		}

		public static float NextFloatInclusive()
		{
			return Math.Clamp((float)NextDoubleInclusive(), 0f, 1f);
		}

		public static double NextDoubleInclusive()
		{
			return Math.Clamp((double)_rand.Next(0, 10001) * 0.0001, 0.0, 1.0);
		}

		public static float NextFloat()
		{
			return (float)_rand.NextDouble();
		}

		public static bool CanDoBy(float chance01)
		{
			return NextFloat() <= chance01;
		}

		public static int NextInt()
		{
			return _rand.Next();
		}
	}
	public static class RegexUtil
	{
		private static readonly Regex _vectorRegex = new Regex("-?[0-9.]+");

		public static bool TryParseVectorString(string input, out float[] vectorArray)
		{
			try
			{
				MatchCollection matchCollection = _vectorRegex.Matches(input);
				int count = matchCollection.Count;
				if (count < 1)
				{
					throw new Exception();
				}
				vectorArray = new float[count];
				for (int i = 0; i < count; i++)
				{
					Match match = matchCollection[i];
					vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture);
				}
				return true;
			}
			catch
			{
				vectorArray = null;
				return false;
			}
		}
	}
}
namespace EEC.Utils.Unity
{
	[CallConstructorOnLoad]
	public static class InLevelCoroutine
	{
		[InjectToIl2Cpp]
		private sealed class InLevelCoroutineHandler : MonoBehaviour
		{
		}

		private static InLevelCoroutineHandler _handler;

		static InLevelCoroutine()
		{
			AssetEvents.AllAssetLoaded += AssetEvents_AllAssetLoaded;
			LevelEvents.LevelCleanup += LevelEvents_LevelCleanup;
			SNetEvents.PrepareRecall += SNetEvents_PrepareRecall;
		}

		private static void AssetEvents_AllAssetLoaded()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if ((Object)(object)_handler == (Object)null)
			{
				GameObject val = new GameObject();
				Object.DontDestroyOnLoad((Object)val);
				_handler = val.AddComponent<InLevelCoroutineHandler>();
			}
		}

		private static void SNetEvents_PrepareRecall(eBufferType _)
		{
			StopAll();
		}

		private static void LevelEvents_LevelCleanup()
		{
			StopAll();
		}

		public static Coroutine Start(IEnumerator coroutine)
		{
			if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
			{
				return ((MonoBehaviour)_handler).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(coroutine));
			}
			return null;
		}

		public static void Stop(Coroutine coroutine)
		{
			if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
			{
				((MonoBehaviour)_handler).StopCoroutine(coroutine);
			}
		}

		public static void StopAll()
		{
			if ((Object)(object)_handler != (Object)null)
			{
				((MonoBehaviour)_handler).StopAllCoroutines();
			}
		}
	}
	public struct LazyTimer
	{
		private float _lastTickTime;

		private float _durationInv;

		public float PassedTime { get; private set; }

		public float Duration { get; private set; }

		public bool Done => Progress >= 1f;

		public float Progress => Mathf.Clamp01(ProgressUnclamped);

		public float ProgressUnclamped
		{
			get
			{
				if (Duration != 0f)
				{
					return PassedTime * _durationInv;
				}
				return 1f;
			}
		}

		public LazyTimer(float duration)
		{
			PassedTime = 0f;
			Duration = duration;
			_durationInv = 1f / duration;
			_lastTickTime = GetTime();
		}

		public void Reset(float newDuration = -1f)
		{
			PassedTime = 0f;
			if (newDuration >= 0f)
			{
				Duration = newDuration;
				_durationInv = 1f / newDuration;
			}
			_lastTickTime = GetTime();
		}

		public void Tick()
		{
			float time = GetTime();
			float num = time - _lastTickTime;
			_lastTickTime = time;
			PassedTime += num;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}

		private static float GetTime()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)GameStateManager.CurrentStateName == 10)
			{
				return Clock.ExpeditionProgressionTime;
			}
			return Clock.Time;
		}
	}
	public struct Timer
	{
		private float _durationInv;

		public float PassedTime { get; private set; }

		public float Duration { get; private set; }

		public bool Done => Progress >= 1f;

		public float Progress => Mathf.Clamp01(ProgressUnclamped);

		public float ProgressUnclamped
		{
			get
			{
				if (Duration != 0f)
				{
					return PassedTime * _durationInv;
				}
				return 1f;
			}
		}

		public Timer(float duration)
		{
			PassedTime = 0f;
			Duration = duration;
			_durationInv = 1f / duration;
		}

		public void Reset(float newDuration = -1f)
		{
			PassedTime = 0f;
			if (newDuration >= 0f)
			{
				Duration = newDuration;
				_durationInv = 1f / newDuration;
			}
		}

		public void Tick()
		{
			PassedTime += Time.deltaTime;
		}

		public void Tick(float deltaTime)
		{
			PassedTime += deltaTime;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}

		public bool TickAndCheckDone(float deltaTime)
		{
			Tick(deltaTime);
			return Done;
		}
	}
	public struct DoubleTimer
	{
		private double _durationInv;

		public double PassedTime { get; private set; }

		public double Duration { get; private set; }

		public bool Done => Progress >= 1.0;

		public double Progress => Math.Clamp(0.0, 1.0, ProgressUnclamped);

		public double ProgressUnclamped
		{
			get
			{
				if (Duration != 0.0)
				{
					return PassedTime * _durationInv;
				}
				return 1.0;
			}
		}

		public DoubleTimer(double duration)
		{
			PassedTime = 0.0;
			Duration = duration;
			_durationInv = 1.0 / duration;
		}

		public void Reset(double newDuration = -1.0)
		{
			PassedTime = 0.0;
			if (newDuration >= 0.0)
			{
				Duration = newDuration;
				_durationInv = 1.0 / newDuration;
			}
		}

		public void Tick()
		{
			PassedTime += Time.deltaTime;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}
	}
	public static class WaitFor
	{
		public static readonly WaitForEndOfFrame EndOfFrame = new WaitForEndOfFrame();

		public static readonly WaitForFixedUpdate FixedUpdate = new WaitForFixedUpdate();

		public static readonly WaitForSecondsCollection Seconds = new WaitForSecondsCollection();

		public static readonly WaitForSecondsRealtimeCollection SecondsRealtime = new WaitForSecondsRealtimeCollection();
	}
	public sealed class WaitForSecondsCollection : WaitForCollection<WaitForSeconds>
	{
		protected override WaitForSeconds CreateInstance(float time)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			return new WaitForSeconds(time);
		}
	}
	public sealed class WaitForSecondsRealtimeCollection : WaitForCollection<WaitForSecondsRealtime>
	{
		protected override WaitForSecondsRealtime CreateInstance(float time)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			return new WaitForSecondsRealtime(time);
		}
	}
	public abstract class WaitForCollection<T>
	{
		private readonly Dictionary<int, T> _lookup = new Dictionary<int, T>(100);

		private T _temp;

		public T this[float time]
		{
			get
			{
				int key = ((!(time <= 0f)) ? Mathf.RoundToInt(time * 1000f) : 0);
				if (_lookup.TryGetValue(key, out _temp))
				{
					return _temp;
				}
				_temp = CreateInstance(time);
				_lookup[key] = _temp;
				return _temp;
			}
		}

		protected abstract T CreateInstance(float time);
	}
}
namespace EEC.Utils.Json
{
	public static class JSON
	{
		private static readonly JsonSerializerOptions _setting;

		static JSON()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new ColorConverter());
			_setting.Converters.Add(new LocalizedTextConverter());
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add(new Vector2Converter());
			_setting.Converters.Add(new Vector3Converter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				Logger.Log("PartialData Support Found!");
			}
		}

		public static T Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _setting);
		}

		public static object Deserialize(Type type, string json)
		{
			return JsonSerializer.Deserialize(json, type, _setting);
		}

		public static string Serialize(object value, Type type)
		{
			return JsonSerializer.Serialize(value, type, _setting);
		}
	}
}
namespace EEC.Utils.Json.Elements
{
	[JsonConverter(typeof(AgentModeTargetConverter))]
	public struct AgentModeTarget
	{
		public static readonly AgentModeTarget All = new AgentModeTarget(AgentModeType.Off | AgentModeType.Hibernate | AgentModeType.Agressive | AgentModeType.Scout | AgentModeType.Patrolling);

		public static readonly AgentModeTarget Scout = new AgentModeTarget(AgentModeType.Scout);

		public static readonly AgentModeTarget Hibernate = new AgentModeTarget(AgentModeType.Hibernate);

		public static readonly AgentModeTarget Agressive = new AgentModeTarget(AgentModeType.Agressive);

		public static readonly AgentModeTarget None = new AgentModeTarget(AgentModeType.None);

		public AgentModeType Mode;

		public AgentModeTarget(AgentModeType modes)
		{
			Mode = modes;
		}

		public bool IsMatch(EnemyAgent agent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0031: Expected I4, but got Unknown
			if ((Object)(object)agent == (Object)null)
			{
				return false;
			}
			AgentMode mode = ((AgentAI)agent.AI).Mode;
			return (int)mode switch
			{
				0 => Mode.HasFlag(AgentModeType.Off), 
				4 => Mode.HasFlag(AgentModeType.Hibernate), 
				1 => Mode.HasFlag(AgentModeType.Agressive), 
				3 => Mode.HasFlag(AgentModeType.Scout), 
				2 => Mode.HasFlag(AgentModeType.Patrolling), 
				_ => false, 
			};
		}
	}
	[Flags]
	public enum AgentModeType
	{
		None = 0,
		Off = 1,
		Hibernate = 2,
		Agressive = 4,
		Scout = 8,
		Patrolling = 0x10
	}
	public sealed class AgentModeTargetConverter : JsonConverter<AgentModeTarget>
	{
		private static readonly char[] _separators = new char[2] { ',', '|' };

		public override AgentModeTarget Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				string[] array = @string.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
				if (array.Length == 0)
				{
					throw new JsonException("There are no entries in " + @string + "! Are you sure it's in right format?");
				}
				AgentModeType agentModeType = AgentModeType.None;
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					switch (array2[i].ToLowerInvariant().Trim())
					{
					case "off":
					case "dead":
						agentModeType |= AgentModeType.Off;
						break;
					case "agressive":
					case "combat":
						agentModeType |= AgentModeType.Agressive;
						break;
					case "hibernate":
					case "hibernation":
					case "hibernating":
					case "sleeping":
						agentModeType |= AgentModeType.Hibernate;
						break;
					case "scout":
					case "scoutpatrolling":
						agentModeType |= AgentModeType.Scout;
						break;
					case "patrolling":
						agentModeType |= AgentModeType.Patrolling;
						break;
					}
				}
				return new AgentModeTarget(agentModeType);
			}
			case JsonTokenType.Number:
				Logger.Warning("Found flag number value in AgentModeTarget! : consider changing it to string.");
				return new AgentModeTarget((AgentModeType)reader.GetInt32());
			default:
				throw new JsonException($"Token type: {reader.TokenType} in AgentModeTarget is not supported!");
			}
		}

		public override void Write(Utf8JsonWriter writer, AgentModeTarget value, JsonSerializerOptions options)
		{
			writer.WriteNumberValue((int)value.Mode);
		}
	}
	[JsonConverter(typeof(BoolBaseConverter))]
	public struct BoolBase
	{
		public static readonly BoolBase False = new BoolBase(BoolMode.False);

		public static readonly BoolBase True = new BoolBase(BoolMode.True);

		public static readonly BoolBase Unchanged = new BoolBase(BoolMode.Unchanged);

		public BoolMode Mode;

		public BoolBase(bool mode)
		{
			Mode = (mode ? BoolMode.True : BoolMode.False);
		}

		public BoolBase(BoolMode mode)
		{
			Mode = mode;
		}

		public bool GetValue(bool originalValue)
		{
			switch (Mode)
			{
			case BoolMode.Unchanged:
				return originalValue;
			case BoolMode.True:
				return true;
			case BoolMode.False:
				return false;
			default:
				Logger.Error($"BoolBase.GetValue; Got Unknown Mode: {Mode}!\n{Environment.StackTrace}");
				return originalValue;
			}
		}
	}
	public enum BoolMode
	{
		False,
		True,
		Unchanged
	}
	public sealed class BoolBaseConverter : JsonConverter<BoolBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(BoolBase);
		}

		public override BoolBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
				{
					return BoolBase.Unchanged;
				}
				if (bool.TryParse(text, out var result))
				{
					return new BoolBase(result);
				}
				throw new JsonException("Cannot parse BoolBase string: " + text + "! Are you sure it's in right format?");
			}
			case JsonTokenType.True:
				return BoolBase.True;
			case JsonTokenType.False:
				return BoolBase.False;
			default:
				throw new JsonException($"BoolBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, BoolBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case BoolMode.True:
				writer.WriteBooleanValue(value: true);
				break;
			case BoolMode.False:
				writer.WriteBooleanValue(value: false);
				break;
			case BoolMode.Unchanged:
				writer.WriteStringValue("Unchanged");
				break;
			}
			writer.WriteCommentValue("BoolBase");
		}
	}
	public sealed class CurveWrapper : Collection<CurveKeyFrame>
	{
		public const int KEYFRAME_FRAMECOUNT = 20;

		public const float KEYFRAME_PROGRESS_INV = 0.05f;

		public static readonly CurveWrapper Empty = new CurveWrapper();

		private static readonly List<Keyframe> _keys = new List<Keyframe>();

		public bool HasSetting => base.Count >= 2;

		public bool TryBuildCurve(out AnimationCurve curve)
		{
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_010c: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			if (base.Count < 2)
			{
				curve = null;
				return false;
			}
			CurveKeyFrame[] array = this.OrderBy((CurveKeyFrame x) => x.Time).ToArray();
			_keys.Clear();
			for (int i = 0; i < base.Count - 1; i++)
			{
				CurveKeyFrame curveKeyFrame = array[i];
				CurveKeyFrame curveKeyFrame2 = array[i + 1];
				if (curveKeyFrame.Time > 1f || curveKeyFrame.Time < 0f)
				{
					Logger.Error($"CurveWrapper Time '{curveKeyFrame.Time}' was invalid!, must be range of 0.0 ~ 1.0");
					curve = null;
					return false;
				}
				float num = curveKeyFrame2.Time - curveKeyFrame.Time;
				float num2 = curveKeyFrame2.Value - curveKeyFrame.Value;
				float num3 = num2 / num;
				for (int j = 0; j < 20; j++)
				{
					float num4 = 0.05f * (float)j;
					float time = curveKeyFrame.Time + num * num4;
					float value = curveKeyFrame.Value + num2 * curveKeyFrame.OutEaseType.Evaluate(num4);
					List<Keyframe> keys = _keys;
					Keyframe item = default(Keyframe);
					((Keyframe)(ref item)).time = time;
					((Keyframe)(ref item)).value = value;
					((Keyframe)(ref item)).inTangent = num3;
					((Keyframe)(ref item)).outTangent = num3;
					keys.Add(item);
				}
			}
			curve = new AnimationCurve(_keys.ToArray());
			return true;
		}
	}
	public struct CurveKeyFrame
	{
		public float Time { get; set; }

		public float Value { get; set; }

		public eEasingType OutEaseType { get; set; }
	}
	[JsonConverter(typeof(EventWrapperConverter))]
	public sealed class EventWrapper : IDisposable
	{
		private string _json;

		private WardenObjectiveEventData _cached;

		public EventWrapper(string json)
		{
			_json = json;
		}

		public void Cache()
		{
			_cached = JSON.Deserialize<WardenObjectiveEventData>(_json);
			_json = string.Empty;
		}

		public WardenObjectiveEventData ToEvent()
		{
			if (_cached == null)
			{
				Cache();
			}
			return _cached;
		}

		public void Dispose()
		{
			_json = null;
			_cached = null;
		}
	}
	internal sealed class EventWrapperConverter : JsonConverter<EventWrapper>
	{
		public override bool HandleNull => false;

		public override EventWrapper Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			if (reader.TokenType == JsonTokenType.StartObject)
			{
				using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader))
				{
					return new EventWrapper(jsonDocument.RootElement.ToString());
				}
			}
			throw new JsonException($"{reader.TokenType} is not supported for EventWrapperValue!");
		}

		public override void Write(Utf8JsonWriter writer, EventWrapper value, JsonSerializerOptions options)
		{
		}
	}
	[JsonConverter(typeof(ValueBaseConverter))]
	public struct ValueBase
	{
		public static readonly ValueBase Unchanged = new ValueBase(1f, ValueMode.Rel, fromDefault: true);

		public static readonly ValueBase Zero = new ValueBase(0f, ValueMode.Abs, fromDefault: false);

		public float Value;

		public ValueMode Mode;

		public bool FromDefault;

		public ValueBase(float value = 1f, ValueMode mode = ValueMode.Rel, bool fromDefault = true)
		{
			Value = value;
			Mode = mode;
			FromDefault = fromDefault;
		}

		public float GetAbsValue(float maxValue, float currentValue)
		{
			if (Mode == ValueMode.Rel)
			{
				if (FromDefault)
				{
					return currentValue * Value;
				}
				return maxValue * Value;
			}
			return Value;
		}

		public float GetAbsValue(float baseValue)
		{
			if (Mode == ValueMode.Rel)
			{
				return baseValue * Value;
			}
			return Value;
		}

		public int GetAbsValue(int maxValue, int currentValue)
		{
			return (int)Math.Round(GetAbsValue((float)maxValue, (float)currentValue));
		}

		public int GetAbsValue(int baseValue)
		{
			return (int)Math.Round(GetAbsValue((float)baseValue));
		}

		public override string ToString()
		{
			return $"[Mode: {Mode}, Value: {Value}]";
		}
	}
	public enum ValueMode
	{
		Rel,
		Abs
	}
	public sealed class ValueBaseConverter : JsonConverter<ValueBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(ValueBase);
		}

		public override ValueBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.Number:
				return new ValueBase(reader.GetSingle(), ValueMode.Abs);
			case JsonTokenType.StartObject:
			{
				ValueBase result3 = default(ValueBase);
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return result3;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "value":
						result3.Value = reader.GetSingle();
						break;
					case "mode":
					{
						if (Enum.TryParse<ValueMode>(reader.GetString(), out var result4))
						{
							result3.Mode = result4;
						}
						break;
					}
					case "fromdefault":
						result3.FromDefault = reader.GetBoolean();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			}
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				bool fromDefault = false;
				if (text.EndsWith("of default", StringComparison.OrdinalIgnoreCase))
				{
					fromDefault = true;
					string text2 = text;
					text = text2.Substring(0, text2.Length - 10).TrimEnd();
				}
				if (text.InvariantEndsWith("%"))
				{
					string text2 = text;
					if (float.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result))
					{
						return new ValueBase(result / 100f, ValueMode.Rel, fromDefault);
					}
				}
				else
				{
					if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
					{
						return new ValueBase(1f, ValueMode.Rel, fromDefault: false);
					}
					if (float.TryParse(text, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result2))
					{
						return new ValueBase(result2, ValueMode.Abs);
					}
				}
				throw new JsonException("Cannot parse ValueBase string: " + text + "! Are you sure it's in right format?");
			}
			default:
				throw new JsonException($"ValueBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, ValueBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case ValueMode.Rel:
			{
				if (Mathf.Approximately(value.Value, 1f))
				{
					writer.WriteStringValue("Unchanged");
					break;
				}
				string format = (value.FromDefault ? "{0}% of default" : "{0}%");
				writer.WriteStringValue(string.Format(format, value.Value * 100f));
				break;
			}
			case ValueMode.Abs:
				writer.WriteStringValue(value.Value.ToString());
				break;
			}
			writer.WriteCommentValue("ValueBase");
		}
	}
}
namespace EEC.Utils.Json.Converters
{
	public sealed class ColorConverter : JsonConverter<Color>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(Color);
		}

		public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			Color color = default(Color);
			float result = 1f;
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return color * result;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "r":
						color.r = reader.GetSingle();
						break;
					case "g":
						color.g = reader.GetSingle();
						break;
					case "b":
						color.b = reader.GetSingle();
						break;
					case "a":
						color.a = reader.GetSingle();
						break;
					case "multiplier":
						result = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				string[] array = text.Split("*");
				string text2;
				switch (array.Length)
				{
				case 1:
					result = 1f;
					text2 = array[0].Trim();
					break;
				case 2:
					if (!float.TryParse(array[1].Trim(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result))
					{
						throw new JsonException("Color multiplier is not valid number! (*): " + text);
					}
					text2 = array[0].Trim();
					break;
				default:
					throw new JsonException("Color format has more than two Mutiplier (*): " + text);
				}
				if (ColorUtility.TryParseHtmlString(text2, ref color))
				{
					return color * result;
				}
				if (TryParseColor(text, out color))
				{
					return color * result;
				}
				throw new JsonException("Color format is not right: " + text);
			}
			default:
				throw new JsonException($"ColorJson type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseColor(string input, out Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
			{
				color = Color.white;
				return false;
			}
			if (vectorArray.Length < 3)
			{
				color = Color.white;
				return false;
			}
			float num = 1f;
			if (vectorArray.Length > 3)
			{
				num = vectorArray[3];
			}
			color = new Color(vectorArray[0], vectorArray[1], vectorArray[2], num);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue("#" + ColorUtility.ToHtmlStringRGBA(value));
		}
	}
	public sealed class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				if (!MTFOPartialDataUtil.TryGetId(@string, out var id))
				{
					return new LocalizedText
					{
						Id = 0u,
						UntranslatedText = @string
					};
				}
				return new LocalizedText
				{
					Id = id,
					UntranslatedText = null
				};
			}
			case JsonTokenType.Number:
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			default:
				throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	public sealed class Vector2Converter : JsonConverter<Vector2>
	{
		public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			Vector2 vector = default(Vector2);
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return vector;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					string text2 = @string.ToLowerInvariant();
					if (!(text2 == "x"))
					{
						if (text2 == "y")
						{
							vector.y = reader.GetSingle();
						}
					}
					else
					{
						vector.x = reader.GetSingle();
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (TryParseVector2(text, out vector))
				{
					return vector;
				}
				throw new JsonException("Vector2 format is not right: " + text);
			}
			default:
				throw new JsonException($"Vector2Json type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseVector2(string input, out Vector2 vector)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
			{
				vector = Vector2.zero;
				return false;
			}
			if (vectorArray.Length < 2)
			{
				vector = Vector2.zero;
				return false;
			}
			vector = new Vector2(vectorArray[0], vectorArray[1]);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y})");
		}
	}
	public sealed class Vector3Converter : JsonConverter<Vector3>
	{
		public override bool HandleNull => false;

		public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0002: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vector = default(Vector3);
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return vector;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string? @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "x":
						vector.x = reader.GetSingle();
						break;
					case "y":
						vector.y = reader.GetSingle();
						break;
					case "z":
						vector.z = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (TryParseVector3(text, out vector))
				{
					return vector;
				}
				throw new JsonException("Vector3 format is not right: " + text);
			}
			default:
				throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseVector3(string input, out Vector3 vector)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
			{
				vector = Vector3.zero;
				return false;
			}
			if (vectorArray.Length < 3)
			{
				vector = Vector3.zero;
				return false;
			}
			vector = new Vector3(vectorArray[0], vectorArray[1], vectorArray[2]);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y} {value.z})");
		}
	}
}
namespace EEC.Utils.Integrations
{
	public static class MTFOPartialDataUtil
	{
		public delegate bool TryGetDelegate(string guid, out uint id);

		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		private static readonly TryGetDelegate _tryGetIDDelegate;

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

		static MTFOPartialDataUtil()
		{
			PersistentIDConverter = null;
			LocalizedTextConverter = null;
			IsLoaded = false;
			Initialized = false;
			PartialDataPath = string.Empty;
			ConfigPath = string.Empty;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = obj.GetTypes();
				Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find PersistentIDConverter Class");
				}
				Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class");
				PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: Initialized");
				}
				if ((object)property2 == null)
				{
					throw new Exception("Unable to Find Property: PartialDataPath");
				}
				if ((object)property3 == null)
				{
					throw new Exception("Unable to Find Field: ConfigPath");
				}
				Initialized = (bool)property.GetValue(null);
				PartialDataPath = (string)property2.GetValue(null);
				ConfigPath = (string)property3.GetValue(null);
				_tryGetIDDelegate = (TryGetDelegate)(types.First((Type t) => t.Name == "PersistentIDManager") ?? throw new Exception("Unable to Find PersistentIDManager Class")).GetMethod("TryGetId", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(TryGetDelegate));
				PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
			}
		}

		public static bool TryGetId(string guid, out uint id)
		{
			if (!IsLoaded)
			{
				id = 0u;
				return false;
			}
			if (!Initialized)
			{
				id = 0u;
				return false;
			}
			if (_tryGetIDDelegate == null)
			{
				id = 0u;
				return false;
			}
			return _tryGetIDDelegate(guid, out id);
		}
	}
	public static class MTFOUtil
	{
		public const string PLUGIN_GUID = "com.dak.MTFO";

		public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;

		public static readonly Version MTFO_FORBID;

		public static readonly Version MTFO_V5;

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool HasHotReload { get; private set; }

		public static FieldInfo HotReloaderField { get; private set; }

		public static event Action HotReloaded;

		static MTFOUtil()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			MTFO_FORBID = new Version("4.2.0", false);
			MTFO_V5 = new Version("4.3.5", false);
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			HasHotReload = false;
			HotReloaderField = null;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			Version version = value.Metadata.Version;
			if (version >= MTFO_V5)
			{
				InitMTFO_V5(value);
				return;
			}
			if (version > MTFO_FORBID)
			{
				InitMTFO_V4(value);
				return;
			}
			throw new Exception("You are using unsupported version of MTFO!");
		}

		private static void InitMTFO_V4(PluginInfo info)
		{
			try
			{
				Assembly obj = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Exception thrown while reading path from DataDumper (MTFO V{info.Metadata.Version}): \n{value}");
			}
		}

		private static void InitMTFO_V5(PluginInfo info)
		{
			try
			{
				Assembly obj = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = obj.GetTypes();
				Type obj2 = types.First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo? property = obj2.GetProperty("IsHotReloadEnabled", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: IsHotReloadEnabled");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				HasHotReload = (bool)property.GetValue(null);
				if (HasHotReload)
				{
					HotReloaderField = (types.First((Type t) => t.Name == "HotReloader") ?? throw new Exception("Unable to Find HotReloader Class")).GetField("Current", BindingFlags.Static | BindingFlags.Public) ?? throw new Exception("Unable to Find Field: Current");
				}
				IsLoaded = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Exception thrown while reading metadata from MTFO (V{info.Metadata.Version}): \n{value}");
			}
		}

		internal static void OnHotReloaded(int _)
		{
			MTFOUtil.HotReloaded?.Invoke();
		}
	}
}
namespace EEC.Utils.Integrations.Inject
{
	[HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")]
	internal static class Inject_CM_PageRundown_New
	{
		private static bool _isInjected;

		[HarmonyWrapSafe]
		internal static void Postfix()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (_isInjected)
			{
				return;
			}
			object obj = MTFOUtil.HotReloaderField?.GetValue(null) ?? null;
			if (obj != null)
			{
				FieldInfo field = obj.GetType().GetField("button", BindingFlags.Instance | BindingFlags.NonPublic);
				if ((object)field != null)
				{
					((CM_Item)field.GetValue(obj)).OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)MTFOUtil.OnHotReloaded);
					_isInjected = true;
				}
			}
		}
	}
}
namespace EEC.Patches
{
	[CallConstructorOnLoad]
	public static class PatchManager
	{
		static PatchManager()
		{
			ConfigManager.EnemyPrefabBuilt += PrefabBuilt;
		}

		private static void PrefabBuilt(EnemyAgent agent, EnemyDataBlock enemyData)
		{
			if (ConfigManager.Global.UsingFlyerStuckCheck && enemyData.TryGetBehaviourBlock(out var behaviour) && behaviour.IsFlyer)
			{
				((Component)agent).gameObject.AddComponent<FlyerStuckHandler>().Agent.Value = agent;
				Logger.Debug($"Added Flyer Check to {((GameDataBlockBase<EnemyDataBlock>)(object)enemyData).persistentID}");
			}
		}
	}
}
namespace EEC.Patches.Inject
{
	[HarmonyPatch(typeof(Dam_SyncedDamageBase))]
	internal static class Inject_Patch_HealerEnemies
	{
		[HarmonyPatch("TentacleAttackDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_TentacleDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("MeleeDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_PunchDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("ExplosionDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_ExplosionDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("ShooterProjectileDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_ShooterProjectileDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		private static bool DoHealer(float dam, Dam_SyncedDamageBase damBase)
		{
			if (dam >= 0f)
			{
				return true;
			}
			if (SNet.IsMaster)
			{
				float num = Math.Abs(dam);
				damBase.SendSetHealth(Math.Min(damBase.Health + num, damBase.HealthMax));
			}
			return false;
		}
	}
}
namespace EEC.Patches.Handlers
{
	[InjectToIl2Cpp]
	internal sealed class FlyerStuckHandler : MonoBehaviour
	{
		public Il2CppReferenceField<EnemyAgent> Agent;

		public float UpdateInterval = float.MaxValue;

		public int RetryCount = int.MaxValue;

		private EnemyAgent _agent;

		private Vector3 _firstPosition;

		private Vector2 _lastGoalXZ;

		private Timer _timer;

		private int _tryCount = -1;

		private bool _shouldCheck = true;

		private void Start()
		{
			if (!SNet.IsMaster)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			_agent = Il2CppReferenceField<EnemyAgent>.op_Implicit(Agent);
			if ((Object)(object)_agent == (Object)null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			if (!_agent.EnemyBehaviorData.IsFlyer)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			UpdateInterval = ConfigManager.Global.FlyerStuck_Interval;
			RetryCount = ConfigManager.Global.FlyerStuck_Retry;
		}

		private void FixedUpdate()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (_shouldCheck)
			{
				if ((int)((AgentAI)_agent.AI).Mode != 1 || !_timer.TickAndCheckDone())
				{
					return;
				}
				_timer.Reset(UpdateInterval);
				if (_tryCount == -1)
				{
					_firstPosition = _agent.Position;
					_tryCount = 0;
				}
				else if (Vector3.Distance(_firstPosition, _agent.Position) < 0.1f)
				{
					_tryCount++;
					if (_tryCount >= RetryCount)
					{
						Logger.Debug("Flyer was stuck in Place!");
						((Agent)_agent).m_replicator.Despawn();
					}
				}
				else
				{
					_shouldCheck = false;
				}
				return;
			}
			Vector3 navmeshAgentGoal = _agent.AI.NavmeshAgentGoal;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(navmeshAgentGoal.x, navmeshAgentGoal.z);
			Vector2 val2 = val - _lastGoalXZ;
			if (((Vector2)(ref val2)).sqrMagnitude < 0.1f)
			{
				if (((MachineState<EB_StateBase>)(object)((StateMachine<EB_StateBase>)(object)_agent.AI.m_behaviour).CurrentState).ENUM_ID == 5)
				{
					_tryCount = -1;
					_shouldCheck = true;
				}
			}
			else
			{
				_tryCount = -1;
				_shouldCheck = false;
			}
			_lastGoalXZ = val;
		}

		private void OnDestroy()
		{
			Agent = null;
		}
	}
	[Flags]
	public enum ShitpostType
	{
		ForceOff = -1,
		Enable = 0,
		Dinnerbone = 1
	}
}
namespace EEC.Patches.Handlers.Yes.Yes.Yes.Yes
{
	[CallConstructorOnLoad]
	public static class Shitpost2022
	{
		static Shitpost2022()
		{
			if (Configuration.CanShitpostOf(ShitpostType.Dinnerbone))
			{
				EnemyEvents.Spawned += EnemyEvents_Spawned;
			}
		}

		private static void EnemyEvents_Spawned(EnemyAgent agent)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			NavMarker marker = GuiManager.NavMarkerLayer.PlaceCustomMarker((NavMarkerOption)16, agent.ModelRef.m_markerTagAlign, "<alpha=#44>Dinnerbone", 0f, false);
			marker.SetVisualStates((NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0);
			marker.m_titleSubObj.SetEnabled(false);
			marker.SetPinEnabled(false);
			((MonoBehaviour)(object)agent.AI).StartCoroutine(UpdateMarker(agent, marker));
			agent.AddOnDeadOnce(delegate
			{
				GuiManager.NavMarkerLayer.RemoveMarker(marker);
			});
			Transform boneTransform = agent.Anim.GetBoneTransform((HumanBodyBones)0);
			if ((Object)(object)boneTransform != (Object)null)
			{
				BoneOffsetHandler boneOffsetHandler = ((Component)boneTransform).gameObject.AddComponent<BoneOffsetHandler>();
				boneOffsetHandler.Animator = Il2CppReferenceField<Animator>.op_Implicit(agent.Anim);
				boneOffsetHandler.RotationOffset = Il2CppValueField<Vector3>.op_Implicit(new Vector3(0f, 180f, 0f));
			}
			else
			{
				agent.MainModelTransform.Rotate(Vector3.forward, 180f);
			}
		}

		private static IEnumerator UpdateMarker(EnemyAgent agent, NavMarker marker)
		{
			WaitForSeconds yielder = WaitFor.Seconds[0.25f];
			bool enabled = false;
			yield return yielder;
			while (((Agent)agent).Alive)
			{
				if ((int)marker.m_currentState == 2)
				{
					Vector3 val = agent.Position - ((Component)CameraManager.GetCurrentCamera()).transform.position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (!enabled && sqrMagnitude <= 64f)
					{
						marker.m_titleSubObj.SetEnabled(true);
						enabled = true;
					}
					else if (enabled && sqrMagnitude > 64f)
					{
						marker.m_titleSubObj.SetEnabled(false);
						enabled = false;
					}
				}
				else if (enabled)
				{
					marker.m_titleSubObj.SetEnabled(false);
					enabled = false;
				}
				yield return yielder;
			}
		}
	}
}
namespace EEC.Networking
{
	public static class NetworkManager
	{
		public const ulong LOWEST_STEAMID64 = 76561197960265729uL;

		public static EnemyAgentModeReplicator EnemyAgentModeState { get; private set; } = new EnemyAgentModeReplicator();


		public static EnemyHealthInfoReplicator EnemyHealthState { get; private set; } = new EnemyHealthInfoReplicator();


		public static EnemyAnimEvent EnemyAnim { get; private set; } = new EnemyAnimEvent();


		internal static void Initialize()
		{
			EnemyEvents.Spawned += EnemySpawned;
			EnemyEvents.Despawn += EnemyDespawn;
			EnemyAgentModeState.Initialize();
			EnemyHealthState.Initialize();
			EnemyAnim.Setup();
		}

		private static void EnemySpawned(EnemyAgent agent)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (agent.TryGetSpawnData(out var spawnData))
			{
				EnemyAgentModeReplicator.State state = default(EnemyAgentModeReplicator.State);
				state.mode = spawnData.mode;
				EnemyAgentModeReplicator.State startState = state;
				EnemyAgentModeState.Register(((Agent)agent).GlobalID, startState, delegate(EnemyAgentModeReplicator.State newState)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					ConfigManager.FireAgentModeChangedEvent(agent, newState.mode);
				});
			}
			EnemyHealthInfoReplicator.State state2 = default(EnemyHealthInfoReplicator.State);
			state2.maxHealth = ((Dam_SyncedDamageBase)agent.Damage).HealthMax;
			state2.health = ((Dam_SyncedDamageBase)agent.Damage).Health;
			EnemyHealthInfoReplicator.State startState2 = state2;
			EnemyHealthState.Register(((Agent)agent).GlobalID, startState2, delegate(EnemyHealthInfoReplicator.State newState)
			{
				EnemyDamageEvents.OnHealthUpdated(agent, newState.maxHealth, newState.health);
			});
			((MonoBehaviour)(object)agent.AI).StartCoroutine(CheckHealth(agent));
		}

		private static IEnumerator CheckHealth(EnemyAgent agent)
		{
			WaitForFixedUpdate fixedUpdateYielder = WaitFor.FixedUpdate;
			float health = ((Dam_SyncedDamageBase)agent.Damage).Health;
			while (true)
			{
				if (SNet.IsMaster)
				{
					float health2 = ((Dam_SyncedDamageBase)agent.Damage).Health;
					if (!Mathf.Approximately(health, health2))
					{
						EnemyHealthState.UpdateInfo(agent);
						health = health2;
					}
				}
				yield return fixedUpdateYielder;
			}
		}

		private static void EnemyDespawn(EnemyAgent agent)
		{
			EnemyAgentModeState.Deregister(((Agent)agent).GlobalID);
		}
	}
	public delegate void SNetRecallEvent(eBufferType bufferType);
	public delegate void SNetPlayerEvent(SNet_Player player);
	public delegate void SNetPlayerEventWithReason(SNet_Player player, SNet_PlayerEventReason reason);
	public static class SNetEvents
	{
		public static event SNetPlayerEvent AgentSpawned;

		public static event SNetRecallEvent PrepareRecall;

		public static event SNetRecallEvent RecallComplete;

		internal static void OnAgentSpawned(SNet_Player player)
		{
			SNetEvents.AgentSpawned?.Invoke(player);
		}

		internal static void OnPrepareRecall(eBufferType bufferType)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SNetEvents.PrepareRecall?.Invoke(bufferType);
		}

		internal static void OnRecallComplete(eBufferType bufferType)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			SNetEvents.RecallComplete?.Invoke(bufferType);
		}
	}
	internal struct ReplicatorPayload
	{
		public ushort key;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
		public byte[] stateBytes;

		public void Serialize<T>(T stateData) where T : struct
		{
			int num = Marshal.SizeOf(stateData);
			if (num >= 30)
			{
				throw new ArgumentException("StateData Exceed size of 30 : Unable to Serialize", "T");
			}
			byte[] destination = new byte[30];
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false);
			Marshal.Copy(intPtr, destination, 0, num);
			Marshal.FreeHGlobal(intPtr);
			stateBytes = destination;
		}

		public T Deserialize<T>()
		{
			int num = Marshal.SizeOf(typeof(T));
			if (num > stateBytes.Length)
			{
				throw new ArgumentException("StateData Exceed size of 30 : Unable to Deserialize", "T");
			}
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.Copy(stateBytes, 0, intPtr, num);
			T result = (T)Marshal.PtrToStructure(intPtr, typeof(T));
			Marshal.FreeHGlobal(intPtr);
			return result;
		}
	}
	public sealed class StateContext<S> where S : struct
	{
		public bool Registered;

		public Action<S> OnStateChanged;

		public S State;
	}
	public abstract class StateReplicator<S> where S : struct
	{
		private static readonly Dictionary<ushort, StateContext<S>> _lookup = new Dictionary<ushort, StateContext<S>>(500);

		private bool _isInitialized;

		public abstract bool ClearOnLevelCleanup { get; }

		public abstract string GUID { get; }

		public bool IsSetup => _isInitialized;

		public string SetStateName { get; private set; } = string.Empty;


		public string ChangeRequestName { get; private set; } = string.Empty;


		public void Initialize()
		{
			if (!_isInitialized)
			{
				SNetEvents.AgentSpawned += SNetEvents_AgentSpawned;
				if (ClearOnLevelCleanup)
				{
					LevelEvents.LevelCleanup += Clear;
				}
				SetStateName = "EECRp" + GUID + "S";
				ChangeRequestName = "EECRp" + GUID + "R";
				NetworkAPI.RegisterEvent<ReplicatorPayload>(SetStateName, (Action<ulong, ReplicatorPayload>)ReceiveSetState_FromMaster);
				NetworkAPI.RegisterEvent<ReplicatorPayload>(ChangeRequestName, (Action<ulong, ReplicatorPayload>)ReceiveSetState_FromClient);
				_isInitialized = true;
			}
		}

		private void SNetEvents_AgentSpawned(SNet_Player player)
		{
			if (!SNet.IsMaster)
			{
				return;
			}
			foreach (KeyValuePair<ushort, StateContext<S>> item in _lookup)
			{
				ReplicatorPayload replicatorPayload = default(ReplicatorPayload);
				replicatorPayload.key = item.Key;
				ReplicatorPayload replicatorPayload2 = replicatorPayload;
				replicatorPayload2.Serialize(item.Value.State);
				NetworkAPI.InvokeEvent<ReplicatorPayload>(SetStateName, replicatorPayload2, player, (SNet_ChannelType)2);
			}
		}

		public void Register(ushort id, S startState, Action<S> onChanged = null)
		{
			if (TryGetContext(id, out var context))
			{
				if (context.Registered)
				{
					return;
				}
				context.Registered = true;
				context.OnStateChanged = onChanged;
			}
			else
			{
				context = new StateContext<S>
				{
					Registered = true,
					OnStateChanged = onChanged,
					State = startState
				};
				_lookup[id] = context;
			}
			context.OnStateChanged?.Invoke(context.State);
			OnStateChange(id, context.State);
		}

		public void Deregister(ushort id)
		{
			if (TryGetContext(id, out var context) && context.Registered)
			{
				_lookup.Remove(id);
			}
		}

		private void Clear()
		{
			_lookup.Clear();
		}

		public void SetState(ushort id, S state)
		{
			if (TryGetContext(id, out var context) && context.Registered)
			{
				ReplicatorPayload replicatorPayload = default(ReplicatorPayload);
				replicatorPayload.key = id;
				ReplicatorPayload replicatorPayload2 = replicatorPayload;
				replicatorPayload2.Serialize(state);
				if (SNet.IsMaster)
				{
					NetworkAPI.InvokeEvent<ReplicatorPayload>(SetStateName, replicatorPayload2, (SNet_ChannelType)2);
					context.State = state;
					ReceiveSetState_FromMaster(SNet.Master.Lookup, replicatorPayload2);
				}
				else if (SNet.HasMaster)
				{
					NetworkAPI.InvokeEvent<ReplicatorPayload>(ChangeRequestName, replicatorPayload2, SNet.Master, (SNet_ChannelType)2);
					context.State = state;
				}
			}
		}

		public bool TryGetState(ushort id, out S state)
		{
			if (!TryGetContext(id, out var context) || !context.Registered)
			{
				Logger.Warning($"KEY: {id} has not registered; backing to Default");
				state = default(S);
				return false;
			}
			state = context.State;
			return true;
		}

		private void ReceiveSetState_FromMaster(ulong sender, ReplicatorPayload statePacket)
		{
			ushort key = statePacket.key;
			S val = statePacket.Deserialize<S>();
			if (TryGetContext(key, out var context))
			{
				context.State = val;
				if (context.Registered)
				{
					context.OnStateChanged?.Invoke(val);
					OnStateChange(key, val);
				}
			}
			else
			{
				_lookup[key] = new StateContext<S>
				{
					Registered = false,
					State = val
				};
			}
		}

		private void ReceiveSetState_FromClient(ulong sender, ReplicatorPayload statePacket)
		{
			if (SNet.IsMaster)
			{
				SetState(statePacket.key, statePacket.Deserialize<S>());
			}
		}

		public bool TryGetContext(ushort id, out StateContext<S> context)
		{
			return _lookup.TryGetValue(id, out context);
		}

		public virtual void OnStateChange(ushort id, S newState)
		{
		}
	}
	public abstract class SyncedEvent<T> where T : struct
	{
		public delegate void ReceiveHandler(T packet);

		private bool _isSetup;

		public abstract string GUID { get; }

		public bool IsSetup => _isSetup;

		public string EventName { get; private set; } = string.Empty;


		public event ReceiveHandler OnReceive;

		public event ReceiveHandler OnReceiveLocal;

		public void Setup()
		{
			if (!_isSetup)
			{
				EventName = "EEC" + GUID;
				NetworkAPI.RegisterEvent<T>(EventName, (Action<ulong, T>)ReceiveClient_Callback);
				_isSetup = true;
			}
		}

		public void Send(T packetData, SNet_Player target = null)
		{
			if ((Object)(object)target != (Object)null)
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, target, (SNet_ChannelType)2);
			}
			else
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, (SNet_ChannelType)2);
			}
			ReceiveLocal_Callback(packetData);
		}

		private void ReceiveLocal_Callback(T packet)
		{
			ReceiveLocal(packet);
			this.OnReceiveLocal?.Invoke(packet);
			Receive(packet);
			this.OnReceive?.Invoke(packet);
		}

		private void ReceiveClient_Callback(ulong sender, T packet)
		{
			Receive(packet);
			this.OnReceive?.Invoke(packet);
		}

		protected virtual void ReceiveLocal(T packet)
		{
		}

		protected virtual void Receive(T packet)
		{
		}
	}
	internal struct SyncedPlayerEventPayload
	{
		public ulong lookup;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
		public byte[] packetBytes;

		public void Serialize<T>(T packet) where T : struct
		{
			int num = Marshal.SizeOf(packet);
			if (num >= 30)
			{
				throw new ArgumentException("PacketData Exceed size of 30 : Unable to Serialize", "T");
			}
			byte[] destination = new byte[30];
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.StructureToPtr(packet, intPtr, fDeleteOld: false);
			Marshal.Copy(intPtr, destination, 0, num);
			Marshal.FreeHGlobal(intPtr);
			packetBytes = destination;
		}

		public T Deserialize<T>()
		{
			int num = Marshal.SizeOf(typeof(T));
			if (num > packetBytes.Length)
			{
				throw new ArgumentException("Packet Exceed size of 30 : Unable to Deserialize", "T");
			}
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.Copy(packetBytes, 0, intPtr, num);
			T result = (T)Marshal.PtrToStructure(intPtr, typeof(T));
			Marshal.FreeHGlobal(intPtr);
			return result;
		}

		public bool TryGetPlayer(out SNet_Player player)
		{
			if (lookup == 0L)
			{
				player = null;
				return false;
			}
			if (lookup < 76561197960265729L)
			{
				return SNet.Core.TryGetPlayerBot((int)lookup - 1, ref player);
			}
			return SNet.Core.TryGetPlayer(lookup, ref player, false);
		}
	}
	public abstract class SyncedPlayerEvent<T> where T : struct
	{
		public delegate void ReceiveHandler(T packet, SNet_Player receivedPlayer);

		private bool _isSetup;

		public abstract string GUID { get; }

		public abstract bool SendToTargetOnly { get; }

		public abstract bool AllowBots { get; }

		public bool IsSetup => _isSetup;

		public string EventName { get; private set; } = string.Empty;


		public event ReceiveHandler OnReceive;

		public void Setup()
		{
			if (!_isSetup)
			{
				EventName = "EECp" + GUID;
				NetworkAPI.RegisterEvent<SyncedPlayerEventPayload>(EventName, (Action<ulong, SyncedPlayerEventPayload>)Received_Callback);
				_isSetup = true;
			}
		}

		public bool TryGetPlayerAgent(SNet_Player player, out PlayerAgent agent)
		{
			if (!player.HasPlayerAgent)
			{
				agent = null;
				return false;
			}
			agent = ((Il2CppObjectBase)player.m_playerAgent).TryCast<PlayerAgent>();
			return (Object)(object)agent != (Object)null;
		}

		public void SendToPlayers(T packetData, params PlayerAgent[] agents)
		{
			foreach (PlayerAgent val in agents)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Owner == (Object)null))
				{
					SendToPlayer(packetData, val.Owner);
				}
			}
		}

		public void SendToPlayers(T packetData, params SNet_Player[] players)
		{
			foreach (SNet_Player player in players)
			{
				SendToPlayer(packetData, player);
			}
		}

		public void SendToPlayer(T packetData, PlayerAgent agent)
		{
			if (!((Object)(object)agent == (Object)null) && !((Object)(object)agent.Owner == (Object)null))
			{
				SendToPlayer(packetData, agent.Owner);
			}
		}

		public void SendToPlayer(T packetData, SNet_Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				Logger.Error(GetType().Name + " - SyncedPlayerEvent player was null!");
				return;
			}
			if (player.Lookup == 0L)
			{
				Logger.Error(GetType().Name + " - SyncedPlayerEvent lookup for player was 0!");
				return;
			}
			SyncedPlayerEventPayload syncedPlayerEventPayload = default(SyncedPlayerEventPayload);
			syncedPlayerEventPayload.lookup = player.Lookup;
			SyncedPlayerEventPayload syncedPlayerEventPayload2 = syncedPlayerEventPayload;
			syncedPlayerEventPayload2.Serialize(packetData);
			if (player.IsBot)
			{
				if (AllowBots)
				{
					if (SNet.IsMaster)
					{
						Received_Callback(SNet.Master.Lookup, syncedPlayerEventPayload2);
					}
					else if (SNet.HasMaster)
					{
						NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, SNet.Master, (SNet_ChannelType)2);
					}
				}
			}
			else if (player.IsLocal)
			{
				Received_Callback(player.Lookup, syncedPlayerEventPayload2);
			}
			else if (SendToTargetOnly)
			{
				NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, player, (SNet_ChannelType)2);
			}
			else
			{
				NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, (SNet_ChannelType)2);
			}
		}

		private void Received_Callback(ulong sender, SyncedPlayerEventPayload payload)
		{
			if (payload.TryGetPlayer(out var player) && (player.IsBot ? AllowBots : (player.IsLocal || !SendToTargetOnly)))
			{
				Received(payload.Deserialize<T>(), player);
			}
		}

		private void Received(T packet, SNet_Player receivedPlayer)
		{
			Receive(packet, receivedPlayer);
			this.OnReceive?.Invoke(packet, receivedPlayer);
		}

		protected virtual void Receive(T packet, SNet_Player receivedPlayer)
		{
		}
	}
}
namespace EEC.Networking.Replicators
{
	public sealed class EnemyAgentModeReplicator : StateReplicator<EnemyAgentModeReplicator.State>
	{
		public struct State
		{
			public AgentMode mode;
		}

		public override bool ClearOnLevelCleanup => true;

		public override string GUID => "EMD";

		public void SetState(ushort id, AgentMode newMode)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			base.SetState(id, new State
			{
				mode = newMode
			});
		}
	}
	public sealed class EnemyHealthInfoReplicator : StateReplicator<EnemyHealthInfoReplicator.State>
	{
		public struct State
		{
			public float maxHealth;

			public float health;
		}

		public override bool ClearOnLevelCleanup => true;

		public override string GUID => "EHI";

		public void UpdateInfo(EnemyAgent agent)
		{
			SetState(((Agent)agent).GlobalID, new State
			{
				maxHealth = ((Dam_SyncedDamageBase)agent.Damage).HealthMa

Plugins/Doughnut.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Doughnut")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Doughnut")]
[assembly: AssemblyTitle("Doughnut")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Doughnut;

internal class AssetLoader
{
	private static bool _loaded;

	private const string DonutPrefabAssetPath = "assets/doughnut/donutprefab.prefab";

	private static Shader _shader;

	private static AssetBundle _donutBundle;

	internal static GameObject donutPrefab;

	internal static GameObject donutPrefab2;

	internal static GameObject donutPrefab3;

	public static void Load()
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		if (!_loaded)
		{
			byte[] bytes = LoadFromResource("Doughnut.Resources.donutbundle");
			LoadBundle(bytes, out _donutBundle);
			donutPrefab = ((Il2CppObjectBase)LoadAsset(_donutBundle, "assets/doughnut/donutprefab.prefab")).Cast<GameObject>();
			ReplaceMatShader(donutPrefab);
			donutPrefab2 = Object.Instantiate<GameObject>(donutPrefab);
			Material val = ((Il2CppObjectBase)LoadAsset(_donutBundle, "assets/doughnut/doughnutmat2.mat")).Cast<Material>();
			ReplaceMatShader(val);
			donutPrefab2.GetComponentInChildren<Renderer>().sharedMaterial = val;
			DontDestroyAndSetHideFlags((Object)(object)donutPrefab2);
			donutPrefab3 = Object.Instantiate<GameObject>(donutPrefab);
			Material val2 = ((Il2CppObjectBase)LoadAsset(_donutBundle, "assets/doughnut/doughnutmat3.mat")).Cast<Material>();
			ReplaceMatShader(val2);
			donutPrefab3.GetComponentInChildren<Renderer>().sharedMaterial = val2;
			DontDestroyAndSetHideFlags((Object)(object)donutPrefab3);
			ManualLogSource logger = EntryPoint.Logger;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("donutPrefab");
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" is ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)(object)donutPrefab == (Object)null) ? string.Empty : "NOT");
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" null!");
			}
			logger.LogWarning(val3);
			_loaded = true;
		}
	}

	private static void ReplaceMatShader(GameObject go)
	{
		ReplaceMatShader(go.GetComponentInChildren<Renderer>().sharedMaterial);
	}

	private static void ReplaceMatShader(Material mat)
	{
		if ((Object)(object)_shader == (Object)null)
		{
			_shader = Shader.Find("GTFO/Standard");
		}
		mat.shader = _shader;
	}

	public static void LoadBundle(byte[] bytes, out AssetBundle bundle)
	{
		bundle = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(bytes));
		DontDestroyAndSetHideFlags((Object)(object)bundle);
	}

	public static void DontDestroyAndSetHideFlags(Object obj)
	{
		Object.DontDestroyOnLoad(obj);
		obj.hideFlags = (HideFlags)61;
	}

	public static Object LoadAsset(AssetBundle bundle, string path)
	{
		Object val = bundle.LoadAsset(path);
		DontDestroyAndSetHideFlags(val);
		return val;
	}

	public static byte[] LoadFromResource(string resourcePath)
	{
		return GetResource(Assembly.GetCallingAssembly(), resourcePath);
	}

	public static byte[] GetResource(Assembly assembly, string resourcePath)
	{
		Stream manifestResourceStream = assembly.GetManifestResourceStream(resourcePath);
		byte[] array = new byte[manifestResourceStream.Length];
		manifestResourceStream.Read(array, 0, (int)manifestResourceStream.Length);
		return array;
	}
}
[BepInPlugin("dev.aurirex.doughnut", "Doughnut", "0.0.1")]
public class EntryPoint : BasePlugin
{
	public const string GUID = "dev.aurirex.doughnut";

	public const string MOD_NAME = "Doughnut";

	public const string VERSION_STRING = "0.0.1";

	internal static ManualLogSource Logger;

	private static Harmony _harmony;

	public override void Load()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		Logger = ((BasePlugin)this).Log;
		ManualLogSource log = ((BasePlugin)this).Log;
		bool flag = default(bool);
		BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(13, 1, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Initializing ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Doughnut");
		}
		log.LogMessage(val);
		_harmony = new Harmony("dev.aurirex.doughnut");
		_harmony.PatchAll(Assembly.GetExecutingAssembly());
	}
}
internal class Patches
{
	[HarmonyWrapSafe]
	[HarmonyPatch(typeof(GameDataInit), "Initialize")]
	internal static class GameDataInit__Initialize__Patch
	{
		public static void Postfix()
		{
			EntryPoint.Logger.LogMessage((object)"Loading assetbundle ...");
			AssetLoader.Load();
		}
	}

	[HarmonyWrapSafe]
	[HarmonyPatch(typeof(ArtifactPickup_Core), "Setup")]
	internal static class ArtifactPickup_Core__Setup__Patch
	{
		private static Material _material;

		public static void Postfix(ArtifactPickup_Core __instance, ArtifactCategory category)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected I4, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)__instance).gameObject.transform.position;
			IEnumerator enumerator = ((Component)__instance).transform.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Object current = enumerator.Current;
					Transform val = ((Il2CppObjectBase)current).TryCast<Transform>();
					if (((Object)val).name == "artifact_shape" || ((Object)val).name == "artifact_shape_b" || ((Object)val).name == "artifact_shape_c")
					{
						((Component)val).gameObject.SetActive(false);
					}
				}
			}
			finally
			{
				if (enumerator is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}
			GameObject val2 = ((Il2CppObjectBase)Object.Instantiate<GameObject>((GameObject)((int)category switch
			{
				1 => AssetLoader.donutPrefab3, 
				2 => AssetLoader.donutPrefab, 
				_ => AssetLoader.donutPrefab2, 
			}))).TryCast<GameObject>();
			val2.transform.parent = ((Component)__instance).gameObject.transform;
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.EulerRotation(0f, Random.Range(0f, 360f), 0f);
		}
	}
}