Decompiled source of swampmansrevengeonphilyprealpha v0.0.8

BepInEx/plugins/EndskApi.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
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.Json;
using System.Text.Json.Serialization;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BoosterImplants;
using CellMenu;
using EndskApi.Api;
using EndskApi.Enums.EnemyKill;
using EndskApi.Enums.Menus;
using EndskApi.Information.Configs;
using EndskApi.Information.EnemyKill;
using EndskApi.Information.Menus;
using EndskApi.Information.WeaponSwitcher;
using EndskApi.Manager;
using EndskApi.Manager.Internal;
using EndskApi.NativePatches;
using EndskApi.Patches.Checkpoint;
using EndskApi.Patches.EndLevel;
using EndskApi.Patches.Init;
using EndskApi.Patches.StartLevel;
using EndskApi.Scripts;
using Enemies;
using GTFO.API;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
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 = "")]
[assembly: AssemblyCompany("EndskApi")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")]
[assembly: AssemblyProduct("EndskApi")]
[assembly: AssemblyTitle("EndskApi")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EndskApi
{
	[BepInPlugin("Endskill.EndskApi", "EndskApi", "1.0.1")]
	public class BepInExLoader : BasePlugin
	{
		public const string MODNAME = "EndskApi";

		public const string AUTHOR = "Endskill";

		public const string GUID = "Endskill.EndskApi";

		public const string VERSION = "1.0.1";

		public static Harmony Harmony { get; private set; }

		public static ConfigFile ConfigLoader { get; private set; }

		public override void Load()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			LogManager.SetLogger(((BasePlugin)this).Log);
			LogManager._debugMessagesActive = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.").Value;
			ConfigLoader = ((BasePlugin)this).Config;
			ClassInjector.RegisterTypeInIl2Cpp<BaseMenu>();
			ClassInjector.RegisterTypeInIl2Cpp<MainMenu>();
			Harmony = new Harmony("Endskill.EndskApi");
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "EndskApi";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitc03396b-dirty-master";

		public const string SemVer = "1.0.0+gitc03396b-dirty-master";

		public const string GitRevShort = "c03396b-dirty";

		public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const bool GitIsDirty = true;
	}
}
namespace EndskApi.Util
{
	public static class MtfoUtils
	{
		public static string CustomPath { get; private set; }

		public static string Version { get; private set; }

		public static bool PluginExists { get; private set; }

		static MtfoUtils()
		{
			CustomPath = string.Empty;
			Version = string.Empty;
			PluginExists = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info))
			{
				return;
			}
			PluginExists = true;
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => !x.IsDynamic && x.Location == info.Location);
				if (assembly == null)
				{
					throw new Exception("couldn't locate the MTFO assembly");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.FirstOrDefault((Type x) => x.Name == "ConfigManager");
				Type type2 = types.FirstOrDefault((Type x) => x.Name == "MTFO");
				if (type2 == null)
				{
					throw new Exception("couldn't locate MTFO's EntryPoint");
				}
				if (type == null)
				{
					throw new Exception("couldn't locate MTFO's ConfigManager");
				}
				FieldInfo field = type2.GetField("VERSION", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				if (field == null)
				{
					throw new Exception("couldn't locate MTFO's Version");
				}
				if (field2 == null)
				{
					throw new Exception("couldn't locate MTFO's CustomPath");
				}
				CustomPath = (string)field2.GetValue(null);
				Version = (string)field.GetValue(null);
				Type type3 = types.FirstOrDefault((Type x) => x.Name == "HotReloader");
			}
			catch (Exception ex)
			{
				LogManager.Error(ex.ToString());
			}
		}
	}
}
namespace EndskApi.Scripts
{
	public class BaseMenu : MonoBehaviour
	{
		protected static string _currentGeomorph;

		protected static bool _guiInitialized = false;

		protected static GUIStyle _normalStyle;

		protected static GUIStyle _titleStyle;

		protected static readonly float _menuX = 30f;

		protected static readonly float _menuY = (float)(Screen.height / 2) - 100f;

		protected MenuStates _currentState;

		protected List<Tool> _tools;

		public string PageTitle { get; set; }

		protected static string PageTitlePostfix { get; set; } = "";


		public BaseMenu(IntPtr intPtr)
			: base(intPtr)
		{
			_tools = new List<Tool>();
		}

		protected virtual void Update()
		{
			if (_currentState != MenuStates.Deactivated)
			{
				DefaultCheatsInputCheck();
			}
		}

		protected virtual void OnGUI()
		{
			if (_currentState == MenuStates.Active)
			{
				CreateUi(_tools, PageTitle);
			}
		}

		public virtual void SetState(MenuStates newState)
		{
			_currentState = newState;
			if (newState == MenuStates.Deactivated)
			{
				((Behaviour)this).enabled = false;
			}
			else
			{
				((Behaviour)this).enabled = true;
			}
		}

		protected void DefaultCheatsInputCheck()
		{
			foreach (Tool tool in _tools)
			{
				if (tool.CheckInput.CheckKeyDown())
				{
					tool.UseTool(tool);
				}
			}
		}

		[HideFromIl2Cpp]
		public static void CreateUi(List<Tool> cheats, string pageTitle)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (!_guiInitialized)
			{
				_titleStyle = new GUIStyle(GUI.skin.GetStyle("label"))
				{
					fontSize = 22
				};
				_normalStyle = new GUIStyle(GUI.skin.GetStyle("label"))
				{
					fontSize = 20
				};
				_guiInitialized = true;
			}
			GUI.contentColor = Color.white;
			GUI.Label(new Rect(_menuX, _menuY - 25f, 400f, 30f), _currentGeomorph, _normalStyle);
			GUI.Label(new Rect(_menuX, _menuY, 400f, 30f), pageTitle + PageTitlePostfix, _titleStyle);
			float num = 25f;
			foreach (Tool cheat in cheats)
			{
				GUI.Label(new Rect(_menuX, _menuY + num, 400f, 30f), cheat.ToString(), _normalStyle);
				num += 22f;
			}
		}

		[HideFromIl2Cpp]
		protected void ToggleTool(Tool cheat)
		{
			cheat.Toggle();
		}
	}
	internal class MainMenu : BaseMenu
	{
		private Dictionary<Tool, BaseMenu> _toolToMenuMap;

		private List<BaseMenu> _unknownMenus;

		private List<IExtendedTool> _middleMouseClickTools = new List<IExtendedTool>();

		private List<IExtendedTool> _timedTools = new List<IExtendedTool>();

		private List<Tool> _hiddenTools = new List<Tool>();

		private float _lastToolActive = Time.time;

		private (uint enemyId, string enemyName)[] _enemyNamesIdMap;

		private int _currentEnemyIndex = 0;

		private int _keypadCounter;

		[HideFromIl2Cpp]
		internal static MainMenu Instance { get; private set; }

		public int CurrentEnemyIndex
		{
			get
			{
				return _currentEnemyIndex;
			}
			set
			{
				if (value >= _enemyNamesIdMap.Count() || value < 0)
				{
					value = _currentEnemyIndex;
				}
				_currentEnemyIndex = value;
				BaseMenu.PageTitlePostfix = ": " + _enemyNamesIdMap[value].enemyName;
			}
		}

		public MainMenu(IntPtr intPtr)
			: base(intPtr)
		{
			base.PageTitle = "MainMenu";
			_toolToMenuMap = new Dictionary<Tool, BaseMenu>();
			_unknownMenus = new List<BaseMenu>();
			_currentState = MenuStates.HiddenAndActive;
			Instance = this;
		}

		public void Awake()
		{
			Il2CppArrayBase<EnemyDataBlock> allBlocks = GameDataBlockBase<EnemyDataBlock>.GetAllBlocks();
			_enemyNamesIdMap = new(uint, string)[allBlocks.Count];
			for (int i = 0; i < allBlocks.Count; i++)
			{
				_enemyNamesIdMap[i] = (((GameDataBlockBase<EnemyDataBlock>)(object)allBlocks[i]).persistentID, ((GameDataBlockBase<EnemyDataBlock>)(object)allBlocks[i]).name);
			}
			CurrentEnemyIndex = 0;
		}

		[HideFromIl2Cpp]
		public void ActivateUnknownMenu<TScript>(TScript menu) where TScript : BaseMenu
		{
			MenuToggleUpdated(null, newToggle: false);
			_currentState = MenuStates.HiddenAndActive;
			_unknownMenus.Add(menu);
		}

		[HideFromIl2Cpp]
		public void AddPage(string ToolName, BaseMenu menu)
		{
			AddPage(new Tool(ToolName, GetFreeKeypadInput(), isToggle: false, base.ToggleTool, MenuToggleUpdated), menu);
		}

		[HideFromIl2Cpp]
		public void AddPage(Tool Tool, BaseMenu menu)
		{
			_toolToMenuMap.Add(Tool, menu);
			_tools.Add(Tool);
			_currentState = MenuStates.Active;
		}

		[HideFromIl2Cpp]
		public void AddMiddleMouseClickTool(IExtendedTool Tool)
		{
			_middleMouseClickTools.Add(Tool);
		}

		public void RemoveMiddleMouseClickTool(IExtendedTool Tool)
		{
			_middleMouseClickTools.Remove(Tool);
		}

		public void AddTimedTool(IExtendedTool tool)
		{
			_timedTools.Add(tool);
		}

		public void RemoveTimedTool(IExtendedTool tool)
		{
			_timedTools.Remove(tool);
		}

		public void AddHiddenTool(Tool tool)
		{
			_hiddenTools.Add(tool);
		}

		public void RemoveHiddenTool(Tool tool)
		{
			_hiddenTools.Remove(tool);
		}

		protected override void Update()
		{
			if (Input.GetKeyDown((KeyCode)277))
			{
				if (_currentState == MenuStates.Active || _currentState == MenuStates.HiddenAndActive)
				{
					_currentState = MenuStates.Deactivated;
				}
				else
				{
					_currentState = MenuStates.Active;
				}
				foreach (KeyValuePair<Tool, BaseMenu> item in _toolToMenuMap)
				{
					item.Key.CurrentToggleState = false;
					item.Value.SetState(MenuStates.Deactivated);
				}
			}
			if (_currentState != MenuStates.Deactivated)
			{
				foreach (Tool hiddenTool in _hiddenTools)
				{
					if (hiddenTool.CheckInput.CheckKeyDown())
					{
						hiddenTool.UseTool(hiddenTool);
					}
				}
			}
			base.Update();
			MainMenuSpecificUpdate();
		}

		private void MainMenuSpecificUpdate()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Invalid comparison between Unknown and I4
			if (Input.GetKeyDown((KeyCode)275))
			{
				CurrentEnemyIndex++;
			}
			if (Input.GetKeyDown((KeyCode)276))
			{
				CurrentEnemyIndex--;
			}
			if (Input.GetMouseButtonDown(2))
			{
				foreach (IExtendedTool middleMouseClickTool in _middleMouseClickTools)
				{
					middleMouseClickTool.ExtraToolAction(GetInformationPackage(middleMouseClickTool.InformationId));
				}
			}
			if (!(_lastToolActive < Time.time))
			{
				return;
			}
			foreach (IExtendedTool timedTool in _timedTools)
			{
				timedTool.ExtraToolAction(GetInformationPackage(timedTool.InformationId));
			}
			if ((int)GameStateManager.CurrentStateName == 10)
			{
				BaseMenu._currentGeomorph = ((Object)((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode.m_area.m_geomorph).name;
			}
			else
			{
				BaseMenu._currentGeomorph = "";
			}
			_lastToolActive = Time.time + 0.25f;
		}

		private object GetInformationPackage(InformationId id)
		{
			return id switch
			{
				InformationId.None => null, 
				InformationId.EnemyId => _enemyNamesIdMap[CurrentEnemyIndex], 
				_ => null, 
			};
		}

		private void MenuToggleUpdated(Tool Tool, bool newToggle)
		{
			foreach (BaseMenu unknownMenu in _unknownMenus)
			{
				unknownMenu.SetState(MenuStates.Deactivated);
			}
			_unknownMenus.Clear();
			foreach (KeyValuePair<Tool, BaseMenu> item in _toolToMenuMap)
			{
				if (item.Key.Equals(Tool))
				{
					item.Value.SetState((!newToggle) ? MenuStates.Deactivated : MenuStates.Active);
					item.Key.CurrentToggleState = newToggle;
				}
				else
				{
					item.Key.CurrentToggleState = false;
					item.Value.SetState(MenuStates.Deactivated);
				}
			}
			_currentState = (_toolToMenuMap.Any<KeyValuePair<Tool, BaseMenu>>((KeyValuePair<Tool, BaseMenu> it) => it.Key.CurrentToggleState) ? MenuStates.HiddenAndActive : MenuStates.Active);
		}

		private InputTool GetFreeKeypadInput()
		{
			_keypadCounter++;
			switch (_keypadCounter)
			{
			case 1:
				return MenuInputProvider.KeyPad1;
			case 2:
				return MenuInputProvider.KeyPad2;
			case 3:
				return MenuInputProvider.KeyPad3;
			case 4:
				return MenuInputProvider.KeyPad4;
			case 5:
				return MenuInputProvider.KeyPad5;
			case 6:
				return MenuInputProvider.KeyPad6;
			case 7:
				return MenuInputProvider.KeyPad7;
			case 8:
				return MenuInputProvider.KeyPad8;
			case 9:
				return MenuInputProvider.KeyPad9;
			default:
				LogManager.Error("There are no free Keypad keys, for the added Menu page!\nPlease ask @Endskill#4992 to finally do his Page system.");
				throw new IndexOutOfRangeException("There are no free keypad keys to add this specific page.");
			}
		}
	}
}
namespace EndskApi.Patches.StartLevel
{
	[HarmonyPatch(typeof(GS_InLevel))]
	internal class GsInLevelPatches
	{
		[HarmonyPatch("Enter")]
		[HarmonyPostfix]
		public static void EnterLevelPostfix()
		{
			LevelApi.InvokeStartLevelCallbacks();
		}
	}
}
namespace EndskApi.Patches.Init
{
	[HarmonyPatch(typeof(GuiManager))]
	internal class GUIManagerPatches
	{
		[HarmonyPatch("Setup")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static void SetupPrefix()
		{
			InitApi.InvokeInitCallbacks();
		}
	}
	[HarmonyPatch(typeof(CM_PageRundown_New))]
	internal class PageRundownNewPatches
	{
		[HarmonyPatch("PlaceRundown")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		public static void PlaceRundownPostFix()
		{
			InitApi.InvokeInitCallbacks();
		}
	}
}
namespace EndskApi.Patches.EnemyKill
{
	[HarmonyBefore(new string[] { "Endskill.EndskApi", "com.dak.DamageNumbers" })]
	[HarmonyPatch(typeof(Dam_EnemyDamageBase))]
	internal class EnemyDamageBasePatches
	{
		[HarmonyPatch("ReceiveMeleeDamage")]
		[HarmonyPrefix]
		public static void MeleePrefix(Dam_EnemyDamageBase __instance, out bool __state)
		{
			__state = ((Agent)__instance.Owner).Alive;
		}

		[HarmonyPatch("ReceiveMeleeDamage")]
		[HarmonyPostfix]
		public static void MeleePostfix(Dam_EnemyDamageBase __instance, bool __state, pFullDamageData data)
		{
			if (!__state)
			{
				return;
			}
			Agent val = default(Agent);
			((pAgent)(ref data.source)).TryGet(ref val);
			if (val != null)
			{
				PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
				DamageDistributionAddDamageDealt(__instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax));
				if (!((Agent)__instance.Owner).Alive)
				{
					EnemyDied(__instance.Owner, val2, LastHitType.Melee);
				}
			}
		}

		[HarmonyPatch("ReceiveBulletDamage")]
		[HarmonyPrefix]
		public static void BulletPrefix(Dam_EnemyDamageBase __instance, out bool __state)
		{
			__state = ((Agent)__instance.Owner).Alive;
		}

		[HarmonyPatch("ReceiveBulletDamage")]
		[HarmonyPostfix]
		public static void BulletPostfix(Dam_EnemyDamageBase __instance, bool __state, pBulletDamageData data)
		{
			if (!__state)
			{
				return;
			}
			Agent val = default(Agent);
			((pAgent)(ref data.source)).TryGet(ref val);
			if (val != null)
			{
				PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
				DamageDistributionAddDamageDealt(__instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax));
				if (!((Agent)__instance.Owner).Alive)
				{
					EnemyDied(__instance.Owner, val2, LastHitType.ShootyWeapon);
				}
			}
		}

		[HarmonyPatch("ExplosionDamage")]
		[HarmonyPrefix]
		public static void ExplosionPrefix(Dam_EnemyDamageBase __instance, out bool __state)
		{
			__state = ((Agent)__instance.Owner).Alive && SNet.IsMaster;
		}

		[HarmonyPatch("ExplosionDamage")]
		[HarmonyPostfix]
		public static void ExplosionPostfix(Dam_EnemyDamageBase __instance, bool __state)
		{
			if (__state && !((Agent)__instance.Owner).Alive)
			{
				EnemyDied(__instance.Owner, null, LastHitType.Explosion);
			}
		}

		private static void DamageDistributionAddDamageDealt(EnemyAgent hitEnemy, PlayerAgent damageDealer, float damageDealt)
		{
			Dictionary<string, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<string, EnemyKillDistribution>>("EndskApi");
			if (!instance.ContainsKey(((Object)hitEnemy).name))
			{
				EnemyKillDistribution enemyKillDistribution = new EnemyKillDistribution(hitEnemy);
				enemyKillDistribution.AddDamageDealtByPlayerAgent(damageDealer, damageDealt);
				instance[((Object)hitEnemy).name] = enemyKillDistribution;
			}
			else
			{
				instance[((Object)hitEnemy).name].AddDamageDealtByPlayerAgent(damageDealer, damageDealt);
			}
		}

		private static void EnemyDied(EnemyAgent hitEnemy, PlayerAgent lastHit, LastHitType lastHitType)
		{
			Dictionary<string, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<string, EnemyKillDistribution>>("EndskApi");
			if (instance.TryGetValue(((Object)hitEnemy).name, out var value))
			{
				value.LastHitDealtBy = lastHit;
				value.lastHitType = lastHitType;
				EnemyKillApi.InvokeEnemyKilledCallbacks(value);
			}
		}
	}
}
namespace EndskApi.Patches.EndLevel
{
	[HarmonyPatch(typeof(GS_AfterLevel))]
	public class GsAfterLevelPatches
	{
		[HarmonyPatch("CleanupAfterExpedition")]
		[HarmonyPrefix]
		public static void CleanupPrefix()
		{
			LevelApi.InvokeEndLevelCallbacks();
		}
	}
}
namespace EndskApi.Patches.Checkpoint
{
	[HarmonyPatch(typeof(CheckpointManager))]
	internal static class CheckpointManagerPatches
	{
		[HarmonyPatch("StoreCheckpoint")]
		[HarmonyPostfix]
		public static void StoreCheackpointPostfix()
		{
			CheckpointApi.InvokeCheckpointReachedCallbacks();
			NetworkManager.SendCheckpointReached();
		}

		[HarmonyPatch("OnLevelCleanup")]
		[HarmonyPostfix]
		public static void OnLevelCleanupPostfix()
		{
			CheckpointApi.InvokeCheckpointCleanupCallbacks();
			NetworkManager.SendCheckpointCleanups();
		}
	}
}
namespace EndskApi.NativePatches
{
	internal class EnemyDamageBaseNatviePatches
	{
		public unsafe delegate void ReceiveMeleeDamage(IntPtr _this, pFullDamageData* data, Il2CppMethodInfo* methodInfo);

		public unsafe delegate void ReceiveBulletDamage(IntPtr _this, pBulletDamageData* data, Il2CppMethodInfo* methodInfo);

		public unsafe delegate void ReceiveExplosionDamage(IntPtr _this, pExplosionDamageData* data, Il2CppMethodInfo* methodInfo);

		public unsafe delegate bool ProcessReceivedDamage(IntPtr _this, float damage, IntPtr _damageSource, Vector3* position, Vector3* direction, ES_HitreactType hitreact, [MarshalAs(UnmanagedType.I1)] bool tryForceHitreact, int limbID, float staggerDamageMulti, DamageNoiseLevel damageNoiseLevel, Il2CppMethodInfo* methodInfo);

		private readonly ReceiveMeleeDamage _originalReceiveMeleeDamage;

		private readonly ReceiveBulletDamage _originalReceiveBulletDamage;

		private readonly ReceiveExplosionDamage _originalReceiveExplosionDamage;

		private readonly ProcessReceivedDamage _originalProcessReceivedDamage;

		private readonly List<INativeDetour> _detours;

		public unsafe EnemyDamageBaseNatviePatches()
		{
			_detours = new List<INativeDetour>
			{
				INativeDetour.CreateAndApply<ReceiveMeleeDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveMeleeDamage", "System.Void", false, new string[1] { "pFullDamageData" }), (ReceiveMeleeDamage)ReceiveMeleeDamagePatch, ref _originalReceiveMeleeDamage),
				INativeDetour.CreateAndApply<ReceiveBulletDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveBulletDamage", "System.Void", false, new string[1] { "pBulletDamageData" }), (ReceiveBulletDamage)ReceiveBulletDamagePatch, ref _originalReceiveBulletDamage),
				INativeDetour.CreateAndApply<ReceiveExplosionDamage>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<Dam_EnemyDamageBase>("ReceiveExplosionDamage", "System.Void", false, new string[1] { "pExplosionDamageData" }), (ReceiveExplosionDamage)ReceiveExplosionDamagePatch, ref _originalReceiveExplosionDamage)
			};
		}

		public unsafe void ReceiveMeleeDamagePatch(IntPtr _this, pFullDamageData* data, Il2CppMethodInfo* methodInfo)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			try
			{
				Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this);
				EnemyDamageBasePatchApi.InvokeReceiveMeleePrefix(instance, ref Unsafe.AsRef<pFullDamageData>((void*)data));
				_originalReceiveMeleeDamage(_this, data, methodInfo);
				EnemyDamageBasePatchApi.InvokeReceiveMeleePostfix(instance, ref Unsafe.AsRef<pFullDamageData>((void*)data));
			}
			catch (Exception ex)
			{
				LogManager.Error(ex);
				LogManager.Error(ex.StackTrace);
			}
		}

		public unsafe void ReceiveBulletDamagePatch(IntPtr _this, pBulletDamageData* data, Il2CppMethodInfo* methodInfo)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			try
			{
				Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this);
				EnemyDamageBasePatchApi.InvokeReceiveBulletPrefix(instance, ref Unsafe.AsRef<pBulletDamageData>((void*)data));
				_originalReceiveBulletDamage(_this, data, methodInfo);
				EnemyDamageBasePatchApi.InvokeReceiveBulletPostfix(instance, ref Unsafe.AsRef<pBulletDamageData>((void*)data));
			}
			catch (Exception ex)
			{
				LogManager.Error(ex);
				LogManager.Error(ex.StackTrace);
			}
		}

		public unsafe void ReceiveExplosionDamagePatch(IntPtr _this, pExplosionDamageData* data, Il2CppMethodInfo* methodInfo)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			try
			{
				Dam_EnemyDamageBase instance = new Dam_EnemyDamageBase(_this);
				EnemyDamageBasePatchApi.InvokeReceiveExplosionPrefix(instance, ref Unsafe.AsRef<pExplosionDamageData>((void*)data));
				_originalReceiveExplosionDamage(_this, data, methodInfo);
				EnemyDamageBasePatchApi.InvokeReceiveExplosionPostfix(instance, ref Unsafe.AsRef<pExplosionDamageData>((void*)data));
			}
			catch (Exception ex)
			{
				LogManager.Error(ex);
				LogManager.Error(ex.StackTrace);
			}
		}
	}
}
namespace EndskApi.Manager
{
	public static class LogManager
	{
		private static ManualLogSource logger;

		internal static bool _debugMessagesActive;

		internal static void SetLogger(ManualLogSource log)
		{
			logger = log;
		}

		public static void Verbose(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogInfo(msg);
			}
		}

		public static void Debug(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogDebug(msg);
			}
		}

		public static void Message(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogMessage(msg);
			}
		}

		public static void Error(object msg)
		{
			logger.LogError(msg);
		}

		public static void Warn(object msg)
		{
			logger.LogWarning(msg);
		}
	}
	public static class MenuInputProvider
	{
		private static MenuRebinding _bindings;

		public static InputTool F1 => new InputTool(_bindings.F1, $": [{_bindings.F1}]");

		public static InputTool F2 => new InputTool(_bindings.F2, $": [{_bindings.F2}]");

		public static InputTool F3 => new InputTool(_bindings.F3, $": [{_bindings.F3}]");

		public static InputTool F4 => new InputTool(_bindings.F4, $": [{_bindings.F4}]");

		public static InputTool F5 => new InputTool(_bindings.F5, $": [{_bindings.F5}]");

		public static InputTool F6 => new InputTool(_bindings.F6, $": [{_bindings.F6}]");

		public static InputTool F7 => new InputTool(_bindings.F7, $": [{_bindings.F7}]");

		public static InputTool F8 => new InputTool(_bindings.F8, $": [{_bindings.F8}]");

		public static InputTool F9 => new InputTool(_bindings.F9, $": [{_bindings.F9}]");

		public static InputTool F10 => new InputTool(_bindings.F10, $": [{_bindings.F10}]");

		public static InputTool KeyPad1 => new InputTool(_bindings.Keypad1, $": [{_bindings.Keypad1}]");

		public static InputTool KeyPad2 => new InputTool(_bindings.Keypad2, $": [{_bindings.Keypad2}]");

		public static InputTool KeyPad3 => new InputTool(_bindings.Keypad3, $": [{_bindings.Keypad3}]");

		public static InputTool KeyPad4 => new InputTool(_bindings.Keypad4, $": [{_bindings.Keypad4}]");

		public static InputTool KeyPad5 => new InputTool(_bindings.Keypad5, $": [{_bindings.Keypad5}]");

		public static InputTool KeyPad6 => new InputTool(_bindings.Keypad6, $": [{_bindings.Keypad6}]");

		public static InputTool KeyPad7 => new InputTool(_bindings.Keypad7, $": [{_bindings.Keypad7}]");

		public static InputTool KeyPad8 => new InputTool(_bindings.Keypad8, $": [{_bindings.Keypad8}]");

		public static InputTool KeyPad9 => new InputTool(_bindings.Keypad9, $": [{_bindings.Keypad9}]");

		static MenuInputProvider()
		{
			JsonSerializerOptions options = new JsonSerializerOptions
			{
				Converters = { (JsonConverter)new JsonStringEnumConverter() }
			};
			ConfigEntry<string> val = BepInExLoader.ConfigLoader.Bind<string>("MenuApi", "KeyBindings", "{\"F1\":\"F1\",\"F2\":\"F2\",\"F3\":\"F3\",\"F4\":\"F4\",\"F5\":\"F5\",\"F6\":\"F6\",\"F7\":\"F7\",\"F8\":\"F8\",\"F9\":\"F9\",\"F10\":\"None\",\"Keypad1\":\"Keypad1\",\"Keypad2\":\"Keypad2\",\"Keypad3\":\"Keypad3\",\"Keypad4\":\"Keypad4\",\"Keypad5\":\"Keypad5\",\"Keypad6\":\"Keypad6\",\"Keypad7\":\"Keypad7\",\"Keypad8\":\"Keypad8\",\"Keypad9\":\"Keypad9\"}", "You can remap keys here.");
			_bindings = JsonSerializer.Deserialize<MenuRebinding>(val.Value, options);
		}
	}
}
namespace EndskApi.Manager.Internal
{
	public class InformationCache
	{
		private readonly Dictionary<string, Dictionary<object, object>> _cache;

		public static InformationCache Instance { get; } = new InformationCache();


		public InformationCache()
		{
			_cache = new Dictionary<string, Dictionary<object, object>>();
		}

		public void SaveInformation(object key, object info, string mod)
		{
			GetCacheOfMod(mod)[key] = info;
		}

		public T GetInformation<T>(object key, string mod)
		{
			if (GetCacheOfMod(mod).TryGetValue(key, out object value))
			{
				return (T)value;
			}
			LogManager.Error($"There was no information with the key {key}");
			throw new KeyNotFoundException($"There was no information with the key {key}!");
		}

		public bool TryGetInformation<T>(object key, out T info, string mod, bool logNotFound = true)
		{
			if (GetCacheOfMod(mod).TryGetValue(key, out object value))
			{
				info = (T)value;
				return true;
			}
			if (logNotFound)
			{
				LogManager.Warn($"There was no informaiton with the key {key}");
			}
			info = default(T);
			return false;
		}

		public void RemoveInformation(object key, string mod)
		{
			if (TryGetCacheOfMod(mod, out Dictionary<object, object> cache))
			{
				cache.Remove(key);
			}
		}

		public bool ContainsKey(object key, string mod)
		{
			Dictionary<object, object> cache;
			return TryGetCacheOfMod(mod, out cache) && cache.ContainsKey(key);
		}

		private Dictionary<object, object> GetCacheOfMod(string mod)
		{
			if (!_cache.TryGetValue(mod, out Dictionary<object, object> value))
			{
				value = new Dictionary<object, object>();
				_cache[mod] = value;
			}
			return value;
		}

		private bool TryGetCacheOfMod(string mod, out Dictionary<object, object> cache)
		{
			return _cache.TryGetValue(mod, out cache);
		}
	}
	internal static class NetworkManager
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal struct DummyStruct
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal struct EquipGearStruct
		{
		}

		private const string _sendCheckpointReachedKey = "CheckpointHasBeenReached";

		private const string _sendCheckpointCleanupKey = "CheckpointCleanup";

		public static void Setup()
		{
			NetworkAPI.RegisterEvent<DummyStruct>("CheckpointCleanup", (Action<ulong, DummyStruct>)ReceiveCheckpointCleanup);
			NetworkAPI.RegisterEvent<DummyStruct>("CheckpointHasBeenReached", (Action<ulong, DummyStruct>)ReceiveCheckpointReached);
		}

		private static void ReceiveCheckpointReached(ulong snetPlayer, DummyStruct _)
		{
			CheckpointApi.InvokeCheckpointReachedCallbacks();
		}

		private static void ReceiveCheckpointCleanup(ulong snetPlayer, DummyStruct _)
		{
			CheckpointApi.InvokeCheckpointCleanupCallbacks();
		}

		public static void SendCheckpointReached()
		{
			NetworkAPI.InvokeEvent<DummyStruct>("CheckpointHasBeenReached", default(DummyStruct), (SNet_ChannelType)2);
		}

		public static void SendCheckpointCleanups()
		{
			NetworkAPI.InvokeEvent<DummyStruct>("CheckpointCleanup", default(DummyStruct), (SNet_ChannelType)2);
		}

		public static void SendEquipGear(GearInfo info)
		{
		}
	}
}
namespace EndskApi.Information.WeaponSwitcher
{
	public class GearInfo
	{
		public InventorySlotAmmo InventorySlotAmmo { get; set; }

		public InventorySlot Slot { get; set; }

		public AmmoType AmmoType { get; set; }

		public GearIDRange GearId { get; set; }

		public int AmmunitionInMagazine { get; set; }

		public GearInfo(GearIDRange gearId, int ammunitionInMagazine, InventorySlotAmmo inventorySlotAmmo)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GearId = gearId;
			AmmunitionInMagazine = ammunitionInMagazine;
			InventorySlotAmmo = inventorySlotAmmo;
			AmmoType = inventorySlotAmmo.AmmoType;
			Slot = inventorySlotAmmo.Slot;
		}
	}
}
namespace EndskApi.Information.Menus
{
	public interface IExtendedTool
	{
		Action<object> ExtraToolAction { get; set; }

		InformationId InformationId { get; set; }
	}
	public class InputTool
	{
		public KeyCode InputKey { get; set; }

		public string Postfix { get; set; }

		public InputTool(KeyCode inputKey, string postfix)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			InputKey = inputKey;
			Postfix = postfix;
		}

		public virtual bool CheckKeyDown()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyDown(InputKey);
		}

		public virtual bool CheckKey()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKey(InputKey);
		}
	}
	public class Tool
	{
		public string Text { get; set; }

		public string TextPostfix { get; set; }

		public InputTool CheckInput { get; }

		public Action<Tool> UseTool { get; set; }

		public Action<Tool, bool> OnToggleUpdate { get; set; }

		public bool IsToggle { get; set; }

		public bool CurrentToggleState { get; set; }

		public object Extra { get; set; }

		public Tool()
		{
		}

		public Tool(string text, InputTool input, Action<Tool, bool> onToggleUpdate, bool startState)
		{
			Text = text;
			CheckInput = input;
			IsToggle = true;
			UseTool = ToggleTool;
			OnToggleUpdate = onToggleUpdate;
			CurrentToggleState = startState;
		}

		public Tool(string text, InputTool input, bool isToggle, Action<Tool> useCheat, Action<Tool, bool> onToggleUpdate = null, bool currentToggleState = false)
		{
			Text = text;
			CheckInput = input;
			IsToggle = isToggle;
			UseTool = useCheat;
			OnToggleUpdate = onToggleUpdate;
			CurrentToggleState = currentToggleState;
		}

		public void Toggle()
		{
			CurrentToggleState = !CurrentToggleState;
			OnToggleUpdate?.Invoke(this, CurrentToggleState);
		}

		public override string ToString()
		{
			if (IsToggle)
			{
				return $"{Text}{TextPostfix}{CheckInput.Postfix} {(CurrentToggleState ? "ON" : "OFF")}";
			}
			return Text + TextPostfix + CheckInput.Postfix;
		}

		private static void ToggleTool(Tool tool)
		{
			tool.Toggle();
		}
	}
	public class ToolExtended : Tool, IExtendedTool
	{
		public Action<object> ExtraToolAction { get; set; }

		public InformationId InformationId { get; set; }

		public ToolExtended(string text, InputTool input, bool isToggle, Action<Tool> useCheat, Action<object> extraCheatAction, Action<Tool, bool> onToggleUpdate = null, bool currentToggleState = false, InformationId infoId = InformationId.None)
			: base(text, input, isToggle, useCheat, onToggleUpdate, currentToggleState)
		{
			ExtraToolAction = extraCheatAction;
			InformationId = infoId;
		}

		public override string ToString()
		{
			return base.ToString();
		}
	}
}
namespace EndskApi.Information.EnemyKill
{
	public class EnemyKillDistribution
	{
		public EnemyAgent KilledEnemyAgent { get; set; }

		public List<DamageDistribution> DamageDistributions { get; set; }

		public PlayerAgent LastHitDealtBy { get; set; }

		public LastHitType lastHitType { get; set; }

		public EnemyKillDistribution(EnemyAgent agentToKill)
		{
			KilledEnemyAgent = agentToKill;
			DamageDistributions = new List<DamageDistribution>();
		}

		public void AddDamageDealtByPlayerAgent(PlayerAgent agent, float damage)
		{
			DamageDistributions.Add(new DamageDistribution(agent.PlayerSlotIndex, damage));
		}

		public float GetDamageDealtBySnet(SNet_Player player)
		{
			int slotIndex = player.PlayerSlotIndex();
			return DamageDistributions.Where((DamageDistribution it) => it.PlayerSlotIndex == slotIndex).Sum((DamageDistribution it) => it.DamageDealt);
		}
	}
	public class DamageDistribution
	{
		public int PlayerSlotIndex { get; set; }

		public float DamageDealt { get; set; }

		public DamageDistribution(int slotIndex, float damage)
		{
			PlayerSlotIndex = slotIndex;
			DamageDealt = damage;
		}
	}
}
namespace EndskApi.Information.Configs
{
	public class MenuRebinding
	{
		public KeyCode F1 { get; set; }

		public KeyCode F2 { get; set; }

		public KeyCode F3 { get; set; }

		public KeyCode F4 { get; set; }

		public KeyCode F5 { get; set; }

		public KeyCode F6 { get; set; }

		public KeyCode F7 { get; set; }

		public KeyCode F8 { get; set; }

		public KeyCode F9 { get; set; }

		public KeyCode F10 { get; set; }

		public KeyCode Keypad1 { get; set; }

		public KeyCode Keypad2 { get; set; }

		public KeyCode Keypad3 { get; set; }

		public KeyCode Keypad4 { get; set; }

		public KeyCode Keypad5 { get; set; }

		public KeyCode Keypad6 { get; set; }

		public KeyCode Keypad7 { get; set; }

		public KeyCode Keypad8 { get; set; }

		public KeyCode Keypad9 { get; set; }

		public MenuRebinding()
		{
			F1 = (KeyCode)282;
			F2 = (KeyCode)283;
			F3 = (KeyCode)284;
			F4 = (KeyCode)285;
			F5 = (KeyCode)286;
			F6 = (KeyCode)287;
			F7 = (KeyCode)288;
			F8 = (KeyCode)289;
			F9 = (KeyCode)290;
			Keypad1 = (KeyCode)257;
			Keypad2 = (KeyCode)258;
			Keypad3 = (KeyCode)259;
			Keypad4 = (KeyCode)260;
			Keypad5 = (KeyCode)261;
			Keypad6 = (KeyCode)262;
			Keypad7 = (KeyCode)263;
			Keypad8 = (KeyCode)264;
			Keypad9 = (KeyCode)265;
		}
	}
}
namespace EndskApi.Information.BoosterInfo
{
	public class BoosterCondition
	{
		public string Name { get; set; }

		public string ShortName { get; set; }

		public BoosterCondition Condition { get; set; }
	}
	public class BoosterEffect
	{
		public string Name { get; set; }

		public string ShortName { get; set; }

		public AgentModifier Effect { get; set; }

		public float Value { get; set; }

		public BoosterEffect(string name, string shortName, AgentModifier effect, float value)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Name = name;
			ShortName = shortName;
			Effect = effect;
			Value = value;
		}
	}
	public interface IBooster
	{
		object Category { get; set; }

		List<BoosterEffect> BoosterEffects { get; set; }

		List<BoosterCondition> BoosterConditions { get; set; }
	}
}
namespace EndskApi.Enums.Menus
{
	public enum InformationId
	{
		None,
		EnemyId
	}
	public enum MenuStates
	{
		Active,
		HiddenAndActive,
		Deactivated
	}
}
namespace EndskApi.Enums.EnemyKill
{
	public enum LastHitType
	{
		Melee,
		ShootyWeapon,
		Explosion
	}
}
namespace EndskApi.Enums.Booster
{
	public enum CustomBoosterCategory
	{
		Muted,
		Bold,
		Aggressive,
		NotAccessible
	}
	public enum CustomBoosterModifiers
	{
		None = 0,
		RegenerationCap = 1,
		RegenerationSpeed = 2,
		HealSupport = 3,
		ReviveSpeedSupport = 4,
		ReviveStartHealthSupport = 5,
		MeleeResistance = 6,
		ProjectileResistance = 7,
		InfectionResistance = 8,
		PistolDamage = 50,
		SMGDamage = 51,
		DMRDamage = 52,
		AssaultRifleDamage = 53,
		CarbineDamage = 54,
		AutoPistolDamage = 55,
		HELDamage = 56,
		ShotgunDamage = 58,
		RevolverDamage = 59,
		SniperDamage = 60,
		BurstCannonDamage = 61,
		MachineGunDamage = 62,
		MachinePistolDamage = 63,
		RifleDamage = 64,
		BurstRifleDamage = 65,
		DoubleTapRifle = 66,
		BullpupRifleDamage = 67,
		CombatShotgunDamage = 68,
		ChokeModShotgunDamage = 69,
		StandardWeaponDamage = 70,
		SpecialWeaponDamage = 71,
		GlueStrength = 100,
		GlueEfficiency = 101,
		SentryGunSpeed = 102,
		SentryGunDamage = 103,
		SentryGunLongRangeDamage = 104,
		SentryGunShortRangeDamage = 105,
		TripMineDamage = 106,
		ScannerRechargeSpeed = 107,
		AmmoSupport = 108,
		HackingProficiency = 150,
		ComputerProcessingSpeed = 151,
		InitialAmmoStandard = 152,
		InitialAmmoSpecial = 153,
		InitialAmmoTool = 154,
		FogRepellerEffect = 155,
		GlowstickEffect = 156,
		BioscanSpeed = 157,
		MeleeDamage = 200
	}
}
namespace EndskApi.Api
{
	public static class CacheApi
	{
		private const string GlobalCache = "GlobalCache";

		internal const string InternalCache = "EndskApi";

		private static readonly InformationCache _informationCache;

		static CacheApi()
		{
			_informationCache = InformationCache.Instance;
		}

		public static void SaveInformation(object key, object info, string mod = "GlobalCache")
		{
			_informationCache.SaveInformation(key, info, mod);
		}

		public static void SaveInstance<T>(T info, string mod = "GlobalCache")
		{
			SaveInformation(typeof(T), info, mod);
		}

		public static T GetInformation<T>(object key, string mod = "GlobalCache")
		{
			return _informationCache.GetInformation<T>(key, mod);
		}

		public static T GetInstance<T>(string mod = "GlobalCache")
		{
			return GetInformation<T>(typeof(T), mod);
		}

		public static bool TryGetInformation<T>(object key, out T information, string mod = "GlobalCache", bool logNotFound = true)
		{
			return _informationCache.TryGetInformation<T>(key, out information, mod, logNotFound);
		}

		public static bool TryGetInstance<T>(out T information, string mod = "GlobalCache", bool logNotFound = true)
		{
			return _informationCache.TryGetInformation<T>(typeof(T), out information, mod, logNotFound);
		}

		public static void RemoveInformation(object key, string mod = "GlobalCache")
		{
			_informationCache.RemoveInformation(key, mod);
		}

		public static void RemoveInstance<T>(string mod = "GlobalCache")
		{
			RemoveInformation(typeof(T), mod);
		}

		public static bool ContainsKey(object key, string mod = "GlobalCache")
		{
			return _informationCache.ContainsKey(key, mod);
		}

		public static InformationCache GetInformationCache()
		{
			return _informationCache;
		}
	}
	public static class CheckpointApi
	{
		private const string CheckpointReachedKey = "CheckpointReachedKey";

		private const string CleanupCheckpointKey = "CheckpointCleanupKey";

		static CheckpointApi()
		{
			BepInExLoader.Harmony.PatchAll(typeof(CheckpointManagerPatches));
		}

		public static void AddCheckpointReachedCallback(Action callBack)
		{
			if (!CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action>();
				CacheApi.SaveInformation("CheckpointReachedKey", information, "EndskApi");
			}
			information.Add(callBack);
		}

		public static void AddCheckpointCleanupCallback(Action callBack)
		{
			if (!CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action>();
				CacheApi.SaveInformation("CheckpointCleanupKey", information, "EndskApi");
			}
			information.Add(callBack);
		}

		public static void RemoveCheckpointReachedCallback(Action callBack)
		{
			if (CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false))
			{
				information.Remove(callBack);
			}
		}

		public static void RemoveCheckpointCleanupCallback(Action callBack)
		{
			if (CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false))
			{
				information.Remove(callBack);
			}
		}

		internal static void InvokeCheckpointReachedCallbacks()
		{
			if (!CacheApi.TryGetInformation<List<Action>>("CheckpointReachedKey", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action item in information)
			{
				item();
			}
		}

		internal static void InvokeCheckpointCleanupCallbacks()
		{
			if (!CacheApi.TryGetInformation<List<Action>>("CheckpointCleanupKey", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action item in information)
			{
				item();
			}
		}
	}
	public static class EnemyDamageBasePatchApi
	{
		public delegate void ReceiveMeleeDamage(Dam_EnemyDamageBase instance, ref pFullDamageData data);

		public delegate void ReceiveBulletDamage(Dam_EnemyDamageBase instance, ref pBulletDamageData data);

		public delegate void ReceiveExplosionDamage(Dam_EnemyDamageBase instance, ref pExplosionDamageData data);

		public delegate void ProcessReceivedDamage(Dam_EnemyDamageBase instance, ref float damage, Agent damageSource, ref Vector3 position, ref Vector3 direction, ref ES_HitreactType hitreact, ref bool tryForceHitreact, ref int limbID, ref float staggerDamageMulti, ref DamageNoiseLevel damageNoiseLevel);

		private static bool _setup;

		internal static List<(double, ReceiveMeleeDamage)> MeleePrefixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveMeleeDamage)>>("EndskApi");
			}
			set
			{
				CacheApi.SaveInstance(value, "EndskApi");
			}
		}

		internal static List<(double, ReceiveMeleeDamage)> MeleePostfixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveMeleeDamage)>>();
			}
			set
			{
				CacheApi.SaveInstance(value);
			}
		}

		internal static List<(double, ReceiveBulletDamage)> BulletPrefixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveBulletDamage)>>("EndskApi");
			}
			set
			{
				CacheApi.SaveInstance(value, "EndskApi");
			}
		}

		internal static List<(double, ReceiveBulletDamage)> BulletPostfixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveBulletDamage)>>();
			}
			set
			{
				CacheApi.SaveInstance(value);
			}
		}

		internal static List<(double, ReceiveExplosionDamage)> ExplosionPrefixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveExplosionDamage)>>("EndskApi");
			}
			set
			{
				CacheApi.SaveInstance(value, "EndskApi");
			}
		}

		internal static List<(double, ReceiveExplosionDamage)> ExplosionPostfixCallbacks
		{
			get
			{
				return CacheApi.GetInstance<List<(double, ReceiveExplosionDamage)>>();
			}
			set
			{
				CacheApi.SaveInstance(value);
			}
		}

		internal static void Setup()
		{
			if (!_setup)
			{
				CacheApi.SaveInstance(new EnemyDamageBaseNatviePatches(), "EndskApi");
				MeleePrefixCallbacks = new List<(double, ReceiveMeleeDamage)>();
				MeleePostfixCallbacks = new List<(double, ReceiveMeleeDamage)>();
				BulletPrefixCallbacks = new List<(double, ReceiveBulletDamage)>();
				BulletPostfixCallbacks = new List<(double, ReceiveBulletDamage)>();
				ExplosionPrefixCallbacks = new List<(double, ReceiveExplosionDamage)>();
				ExplosionPostfixCallbacks = new List<(double, ReceiveExplosionDamage)>();
				_setup = true;
			}
		}

		public static void AddReceiveMeleePrefix(double priority, ReceiveMeleeDamage method)
		{
			Setup();
			MeleePrefixCallbacks.Add((priority, method));
			MeleePrefixCallbacks = new List<(double, ReceiveMeleeDamage)>(MeleePrefixCallbacks.OrderBy<(double, ReceiveMeleeDamage), double>(((double, ReceiveMeleeDamage) x) => x.Item1));
		}

		public static void AddReceiveMeleePostfix(double priority, ReceiveMeleeDamage method)
		{
			Setup();
			MeleePostfixCallbacks.Add((priority, method));
			MeleePostfixCallbacks = new List<(double, ReceiveMeleeDamage)>(MeleePostfixCallbacks.OrderBy<(double, ReceiveMeleeDamage), double>(((double, ReceiveMeleeDamage) x) => x.Item1));
		}

		public static void AddReceiveBulletPrefix(double priority, ReceiveBulletDamage method)
		{
			Setup();
			BulletPrefixCallbacks.Add((priority, method));
			BulletPrefixCallbacks = new List<(double, ReceiveBulletDamage)>(BulletPrefixCallbacks.OrderBy<(double, ReceiveBulletDamage), double>(((double, ReceiveBulletDamage) x) => x.Item1));
		}

		public static void AddReceiveBulletPostfix(double priority, ReceiveBulletDamage method)
		{
			Setup();
			BulletPostfixCallbacks.Add((priority, method));
			BulletPostfixCallbacks = new List<(double, ReceiveBulletDamage)>(BulletPostfixCallbacks.OrderBy<(double, ReceiveBulletDamage), double>(((double, ReceiveBulletDamage) x) => x.Item1));
		}

		public static void AddReceiveExplosionPrefix(double priority, ReceiveExplosionDamage method)
		{
			Setup();
			ExplosionPrefixCallbacks.Add((priority, method));
			ExplosionPrefixCallbacks = new List<(double, ReceiveExplosionDamage)>(ExplosionPrefixCallbacks.OrderBy<(double, ReceiveExplosionDamage), double>(((double, ReceiveExplosionDamage) x) => x.Item1));
		}

		public static void AddReceiveExplosionPostfix(double priority, ReceiveExplosionDamage method)
		{
			Setup();
			ExplosionPostfixCallbacks.Add((priority, method));
			ExplosionPostfixCallbacks = new List<(double, ReceiveExplosionDamage)>(ExplosionPostfixCallbacks.OrderBy<(double, ReceiveExplosionDamage), double>(((double, ReceiveExplosionDamage) x) => x.Item1));
		}

		internal static void InvokeReceiveMeleePrefix(Dam_EnemyDamageBase instance, ref pFullDamageData data)
		{
			foreach (var meleePrefixCallback in MeleePrefixCallbacks)
			{
				meleePrefixCallback.Item2(instance, ref data);
			}
		}

		internal static void InvokeReceiveMeleePostfix(Dam_EnemyDamageBase instance, ref pFullDamageData data)
		{
			foreach (var meleePostfixCallback in MeleePostfixCallbacks)
			{
				meleePostfixCallback.Item2(instance, ref data);
			}
		}

		internal static void InvokeReceiveBulletPrefix(Dam_EnemyDamageBase instance, ref pBulletDamageData data)
		{
			foreach (var bulletPrefixCallback in BulletPrefixCallbacks)
			{
				bulletPrefixCallback.Item2(instance, ref data);
			}
		}

		internal static void InvokeReceiveBulletPostfix(Dam_EnemyDamageBase instance, ref pBulletDamageData data)
		{
			foreach (var bulletPostfixCallback in BulletPostfixCallbacks)
			{
				bulletPostfixCallback.Item2(instance, ref data);
			}
		}

		internal static void InvokeReceiveExplosionPrefix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data)
		{
			foreach (var explosionPrefixCallback in ExplosionPrefixCallbacks)
			{
				explosionPrefixCallback.Item2(instance, ref data);
			}
		}

		internal static void InvokeReceiveExplosionPostfix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data)
		{
			foreach (var explosionPostfixCallback in ExplosionPostfixCallbacks)
			{
				explosionPostfixCallback.Item2(instance, ref data);
			}
		}
	}
	public static class EnemyKillApi
	{
		private const string EnemyKillKey = "EnemyKillCallbacks";

		private static bool _setup = false;

		private static Dictionary<IntPtr, bool> _enemyStates = new Dictionary<IntPtr, bool>();

		public static void AddEnemyKilledCallback(Action<EnemyKillDistribution> callBack)
		{
			Setup();
			if (!CacheApi.TryGetInformation<List<Action<EnemyKillDistribution>>>("EnemyKillCallbacks", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action<EnemyKillDistribution>>();
				CacheApi.SaveInformation("EnemyKillCallbacks", information, "EndskApi");
			}
			information.Add(callBack);
		}

		internal static void InvokeEnemyKilledCallbacks(EnemyKillDistribution enemyKill)
		{
			if (!CacheApi.TryGetInformation<List<Action<EnemyKillDistribution>>>("EnemyKillCallbacks", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action<EnemyKillDistribution> item in information)
			{
				item(enemyKill);
			}
		}

		private static void Setup()
		{
			if (!_setup)
			{
				EnemyDamageBasePatchApi.AddReceiveMeleePrefix(1.0, ReceiveMeleePrefix);
				EnemyDamageBasePatchApi.AddReceiveMeleePostfix(1.0, ReceiveMeleePostfix);
				EnemyDamageBasePatchApi.AddReceiveBulletPrefix(1.0, ReceiveBulletPrefix);
				EnemyDamageBasePatchApi.AddReceiveBulletPostfix(1.0, ReceiveBulletPostfix);
				EnemyDamageBasePatchApi.AddReceiveExplosionPrefix(1.0, ReceiveExplosionPrefix);
				EnemyDamageBasePatchApi.AddReceiveExplosionPostfix(1.0, ReceiveExplosionPostfix);
				CacheApi.SaveInstance(new Dictionary<IntPtr, EnemyKillDistribution>(), "EndskApi");
				LevelApi.AddEndLevelCallback(delegate
				{
					_enemyStates = new Dictionary<IntPtr, bool>();
					CacheApi.SaveInstance(new Dictionary<IntPtr, EnemyKillDistribution>(), "EndskApi");
				});
				_setup = true;
			}
		}

		private static void ReceiveMeleePrefix(Dam_EnemyDamageBase instance, ref pFullDamageData data)
		{
			LogManager.Debug($"Receive Melee EnemyKillApi Prefix State = {((Agent)instance.Owner).Alive}");
			_enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive;
		}

		private static void ReceiveMeleePostfix(Dam_EnemyDamageBase instance, ref pFullDamageData data)
		{
			LogManager.Debug($"Receive Melee EnemyKillApi Postfix State = {((Agent)instance.Owner).Alive}");
			if (!(_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value))
			{
				return;
			}
			Agent val = default(Agent);
			((pAgent)(ref data.source)).TryGet(ref val);
			if (val != null)
			{
				PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
				DamageDistributionAddDamageDealt(instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)instance).HealthMax));
				if (!((Agent)instance.Owner).Alive)
				{
					EnemyDied(instance.Owner, val2, LastHitType.Melee);
				}
			}
		}

		private static void ReceiveBulletPrefix(Dam_EnemyDamageBase instance, ref pBulletDamageData data)
		{
			_enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive;
		}

		private static void ReceiveBulletPostfix(Dam_EnemyDamageBase instance, ref pBulletDamageData data)
		{
			if (!(_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value))
			{
				return;
			}
			Agent val = default(Agent);
			((pAgent)(ref data.source)).TryGet(ref val);
			if (val != null)
			{
				PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
				DamageDistributionAddDamageDealt(instance.Owner, val2, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)instance).HealthMax));
				if (!((Agent)instance.Owner).Alive)
				{
					EnemyDied(instance.Owner, val2, LastHitType.ShootyWeapon);
				}
			}
		}

		private static void ReceiveExplosionPrefix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data)
		{
			_enemyStates[((Il2CppObjectBase)instance).Pointer] = ((Agent)instance.Owner).Alive;
		}

		private static void ReceiveExplosionPostfix(Dam_EnemyDamageBase instance, ref pExplosionDamageData data)
		{
			if (_enemyStates.TryGetValue(((Il2CppObjectBase)instance).Pointer, out var value) && value && !((Agent)instance.Owner).Alive)
			{
				EnemyDied(instance.Owner, null, LastHitType.Explosion);
			}
		}

		private static void DamageDistributionAddDamageDealt(EnemyAgent hitEnemy, PlayerAgent damageDealer, float damageDealt)
		{
			Dictionary<IntPtr, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<IntPtr, EnemyKillDistribution>>("EndskApi");
			if (!instance.ContainsKey(((Il2CppObjectBase)hitEnemy).Pointer))
			{
				EnemyKillDistribution enemyKillDistribution = new EnemyKillDistribution(hitEnemy);
				enemyKillDistribution.AddDamageDealtByPlayerAgent(damageDealer, damageDealt);
				instance[((Il2CppObjectBase)hitEnemy).Pointer] = enemyKillDistribution;
			}
			else
			{
				instance[((Il2CppObjectBase)hitEnemy).Pointer].AddDamageDealtByPlayerAgent(damageDealer, damageDealt);
			}
		}

		private static void EnemyDied(EnemyAgent hitEnemy, PlayerAgent lastHit, LastHitType lastHitType)
		{
			Dictionary<IntPtr, EnemyKillDistribution> instance = CacheApi.GetInstance<Dictionary<IntPtr, EnemyKillDistribution>>("EndskApi");
			if (instance.TryGetValue(((Il2CppObjectBase)hitEnemy).Pointer, out var value))
			{
				value.LastHitDealtBy = lastHit;
				value.lastHitType = lastHitType;
				InvokeEnemyKilledCallbacks(value);
			}
		}
	}
	public static class GearSwitchApi
	{
		static GearSwitchApi()
		{
			LevelApi.AddEndLevelCallback(LevelEndedCallback);
			SetGearInfoCache(new Dictionary<IntPtr, GearInfo>());
		}

		public static GearInfo CreateNewWeaponInfo(InventorySlot slot, AmmoType ammoType, GearIDRange gearId)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_000f: 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_0019: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			PlayerDataBlock block = GameDataBlockBase<PlayerDataBlock>.GetBlock(1u);
			InventorySlotAmmo val = new InventorySlotAmmo();
			val.Slot = slot;
			val.AmmoInPack = (((int)ammoType == 1) ? block.AmmoSpecialInitial : block.AmmoStandardInitial);
			val.AmmoMaxCap = (((int)ammoType == 1) ? block.AmmoSpecialMaxCap : block.AmmoStandardMaxCap);
			GearInfo gearInfo = new GearInfo(gearId, 0, val);
			GearCategoryDataBlock block2 = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(gearId.GetCompID((eGearComponent)2));
			uint archetypeID = GearBuilder.GetArchetypeID(block2, (eWeaponFireMode)gearId.GetCompID((eGearComponent)1));
			ArchetypeDataBlock block3 = GameDataBlockBase<ArchetypeDataBlock>.GetBlock(archetypeID);
			gearInfo.InventorySlotAmmo.BulletClipSize = block3.DefaultClipSize;
			gearInfo.AmmunitionInMagazine = block3.DefaultClipSize;
			LogManager.Debug($"Putting {gearInfo.AmmunitionInMagazine} into {block2.PublicName}");
			return gearInfo;
		}

		public static void EquipGear(GearInfo newGear, out GearInfo oldGear)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			AddWeaponInfo(newGear);
			SyncAmmonitionWithRegisteredWeapon(newGear.Slot, out oldGear);
			EquipGear(newGear);
		}

		public static void SyncAmmonitionWithRegisteredWeapon(InventorySlot slot, out GearInfo changedWeapon)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetItemEquippableInSlot(slot, out ItemEquippable item) && (Object)(object)item != (Object)null)
			{
				LogManager.Debug("SyncAmmunitionWithRegisteredWeapon actually found Weapon itemequippable");
				InventorySlotAmmo inventorySlotAmmo = PlayerBackpackManager.LocalBackpack.AmmoStorage.GetInventorySlotAmmo(slot);
				if (GetGearInfo().TryGetValue(((Il2CppObjectBase)inventorySlotAmmo).Pointer, out changedWeapon))
				{
					changedWeapon.AmmunitionInMagazine = item.GetCurrentClip();
					LogManager.Debug($"Updated Ammo to {changedWeapon.AmmunitionInMagazine}, Max is {changedWeapon.InventorySlotAmmo.BulletClipSize}");
				}
			}
			else
			{
				changedWeapon = null;
			}
		}

		public static void AddWeaponInfo(GearInfo info)
		{
			Dictionary<IntPtr, GearInfo> gearInfo = GetGearInfo();
			if (!gearInfo.ContainsKey(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer))
			{
				gearInfo.Add(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer, info);
			}
		}

		public static void UnregisterWeapon(GearInfo info)
		{
			GetGearInfo().Remove(((Il2CppObjectBase)info.InventorySlotAmmo).Pointer);
		}

		private static void EquipGear(GearInfo info)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			GearInfo info2 = info;
			PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
			localBackpack.SpawnAndEquipGearAsync(info2.Slot, info2.GearId, delBackpackItemCallback.op_Implicit((Action<BackpackItem>)BackPackItemCreatedCallBack));
			SetAmmoStorage(info2, localBackpack.AmmoStorage);
			void BackPackItemCreatedCallBack(BackpackItem backpackItem)
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				ItemEquippable val = ((Il2CppObjectBase)backpackItem.Instance).TryCast<ItemEquippable>();
				if ((Object)(object)val != (Object)null)
				{
					val.SetCurrentClip(info2.AmmunitionInMagazine);
					PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
					localPlayerAgent.Sync.WantsToWieldSlot(info2.Slot, false);
				}
			}
		}

		private static bool TryGetItemEquippableInSlot(InventorySlot slot, out ItemEquippable item)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
			BackpackItem val = default(BackpackItem);
			if (!localBackpack.TryGetBackpackItem(slot, ref val))
			{
				item = null;
				return false;
			}
			item = ((Il2CppObjectBase)val.Instance).TryCast<ItemEquippable>();
			return (Object)(object)item != (Object)null;
		}

		private static void SetAmmoStorage(GearInfo info, PlayerAmmoStorage storage)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//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_0029: Invalid comparison between Unknown and I4
			((Il2CppArrayBase<InventorySlotAmmo>)(object)storage.m_ammoStorage)[(int)info.AmmoType] = info.InventorySlotAmmo;
			AmmoType ammoType = info.AmmoType;
			AmmoType val = ammoType;
			if ((int)val != 0)
			{
				if ((int)val == 1)
				{
					storage.SpecialAmmo = info.InventorySlotAmmo;
				}
			}
			else
			{
				storage.StandardAmmo = info.InventorySlotAmmo;
			}
		}

		internal static void LevelEndedCallback()
		{
			SetGearInfoCache(new Dictionary<IntPtr, GearInfo>());
		}

		private static Dictionary<IntPtr, GearInfo> GetGearInfo()
		{
			return CacheApi.GetInstance<Dictionary<IntPtr, GearInfo>>("EndskApi");
		}

		private static void SetGearInfoCache(Dictionary<IntPtr, GearInfo> dic)
		{
			CacheApi.SaveInstance(dic, "EndskApi");
		}
	}
	public static class InitApi
	{
		private const string InitKey = "InitKey";

		static InitApi()
		{
			BepInExLoader.Harmony.PatchAll(typeof(PageRundownNewPatches));
			BepInExLoader.Harmony.PatchAll(typeof(GUIManagerPatches));
		}

		public static void AddInitCallback(Action callBack)
		{
			if (!CacheApi.TryGetInformation<List<Action>>("InitKey", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action>();
				CacheApi.SaveInformation("InitKey", information, "EndskApi");
			}
			information.Add(callBack);
		}

		internal static void InvokeInitCallbacks()
		{
			if (!CacheApi.TryGetInformation<List<Action>>("InitKey", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action item in information)
			{
				try
				{
					item();
				}
				catch (Exception ex)
				{
					LogManager.Error(ex.ToString());
				}
			}
			CacheApi.RemoveInformation("InitKey", "EndskApi");
		}
	}
	public static class LevelApi
	{
		private const string EndLevelKey = "EndLevelKey";

		private const string StartLevelKey = "StartLevelKey";

		static LevelApi()
		{
			BepInExLoader.Harmony.PatchAll(typeof(GsAfterLevelPatches));
			BepInExLoader.Harmony.PatchAll(typeof(GsInLevelPatches));
		}

		public static void AddBeginLevelCallback(Action callBack)
		{
			if (!CacheApi.TryGetInformation<List<Action>>("StartLevelKey", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action>();
				CacheApi.SaveInformation("StartLevelKey", information, "EndskApi");
			}
			information.Add(callBack);
		}

		public static void AddEndLevelCallback(Action callBack)
		{
			if (!CacheApi.TryGetInformation<List<Action>>("EndLevelKey", out var information, "EndskApi", logNotFound: false))
			{
				information = new List<Action>();
				CacheApi.SaveInformation("EndLevelKey", information, "EndskApi");
			}
			information.Add(callBack);
		}

		internal static void InvokeEndLevelCallbacks()
		{
			if (!CacheApi.TryGetInformation<List<Action>>("EndLevelKey", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action item in information)
			{
				try
				{
					item();
				}
				catch (Exception msg)
				{
					LogManager.Error(msg);
				}
			}
		}

		internal static void InvokeStartLevelCallbacks()
		{
			if (!CacheApi.TryGetInformation<List<Action>>("StartLevelKey", out var information, "EndskApi", logNotFound: false))
			{
				return;
			}
			foreach (Action item in information)
			{
				try
				{
					item();
				}
				catch (Exception msg)
				{
					LogManager.Error(msg);
				}
			}
		}
	}
	public static class MenuApi
	{
		private static bool _setup;

		static MenuApi()
		{
			_setup = false;
		}

		internal static void Setup()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (!_setup)
			{
				GameObject val = new GameObject("EndskApi_Menu");
				CacheApi.SaveInstance(val.AddComponent<MainMenu>(), "EndskApi");
				Object.DontDestroyOnLoad((Object)(object)val);
				_setup = true;
			}
		}

		public static void ActivateUnknownMenu<TScript>(TScript menu) where TScript : BaseMenu
		{
			Setup();
			CacheApi.GetInstance<MainMenu>("EndskApi").ActivateUnknownMenu(menu);
		}

		public static TScript AddMenu<TScript>(string pageName) where TScript : BaseMenu
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			TScript val = ((Component)instance).gameObject.AddComponent<TScript>();
			instance.AddPage(pageName, val);
			CacheApi.SaveInstance(val, "EndskApi");
			return val;
		}

		public static TScript GetMenu<TScript>() where TScript : BaseMenu
		{
			Setup();
			return CacheApi.GetInstance<TScript>("EndskApi");
		}

		public static void AddMiddleMouseClickTool(IExtendedTool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.AddMiddleMouseClickTool(tool);
		}

		public static void RemoveMiddleMouseClickTool(IExtendedTool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.RemoveMiddleMouseClickTool(tool);
		}

		public static void AddTimerTool(IExtendedTool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.AddTimedTool(tool);
		}

		public static void RemoveTimerTool(IExtendedTool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.RemoveTimedTool(tool);
		}

		public static void AddHiddenFunction(Tool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.AddHiddenTool(tool);
		}

		public static void RemoveHiddenFunction(Tool tool)
		{
			Setup();
			MainMenu instance = CacheApi.GetInstance<MainMenu>("EndskApi");
			instance.RemoveHiddenTool(tool);
		}
	}
	public static class ProfileIndependentDataApi
	{
		private static readonly string _localLowPath;

		static ProfileIndependentDataApi()
		{
			string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).Replace("Roaming", "LocalLow");
			_localLowPath = Path.Combine(path, "10 Chambers Collective", "Mods");
			if (!Directory.Exists(_localLowPath))
			{
				Directory.CreateDirectory(_localLowPath);
			}
		}

		public static T Load<T>(string fileName, JsonSerializerOptions option = null) where T : new()
		{
			if (TryLoadFromCache<T>(fileName, out var cachedObj))
			{
				return cachedObj;
			}
			if (option == null)
			{
				option = new JsonSerializerOptions
				{
					IncludeFields = false,
					ReadCommentHandling = JsonCommentHandling.Skip,
					PropertyNameCaseInsensitive = true,
					WriteIndented = true
				};
			}
			if (File.Exists(CreatePath(fileName)))
			{
				return JsonSerializer.Deserialize<T>(File.ReadAllText(CreatePath(fileName)), option);
			}
			return new T();
		}

		public static void Save(object obj, string fileName, JsonSerializerOptions option = null)
		{
			SaveIntoCache(fileName, obj);
			if (option == null)
			{
				option = new JsonSerializerOptions
				{
					IncludeFields = false,
					ReadCommentHandling = JsonCommentHandling.Skip,
					PropertyNameCaseInsensitive = true,
					WriteIndented = true
				};
			}
			File.WriteAllText(CreatePath(fileName), JsonSerializer.Serialize(obj, option));
		}

		internal static bool TryLoadFromCache<T>(string fileName, out T cachedObj)
		{
			return CacheApi.TryGetInformation<T>(fileName, out cachedObj, "ProfileIndependentApi", logNotFound: false);
		}

		internal static void SaveIntoCache(string fileName, object obj)
		{
			CacheApi.SaveInformation(fileName, obj, "ProfileIndependentApi");
		}

		private static string CreatePath(string fileName)
		{
			if (fileName.EndsWith(".json"))
			{
				return Path.Combine(_localLowPath, fileName);
			}
			return Path.Combine(_localLowPath, fileName + ".json");
		}
	}
}

BepInEx/plugins/Expansions.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DoubleJump;
using EndskApi.Api;
using Enemies;
using GTFuckingXP.Communication;
using GTFuckingXP.Extensions;
using GTFuckingXP.Information.Level;
using GTFuckingXP.Managers;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;
using XpExpansions.Extensions;
using XpExpansions.Information;
using XpExpansions.Information.BioTrackerLocal;
using XpExpansions.Information.DoubleJump;
using XpExpansions.Information.StartingXp;
using XpExpansions.Manager;
using XpExpansions.Scripts;

[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 = "")]
[assembly: AssemblyCompany("Expansions")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")]
[assembly: AssemblyProduct("Expansions")]
[assembly: AssemblyTitle("Expansions")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Expansions
{
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "Expansions";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitc03396b-dirty-master";

		public const string SemVer = "1.0.0+gitc03396b-dirty-master";

		public const string GitRevShort = "c03396b-dirty";

		public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const bool GitIsDirty = true;
	}
}
namespace XpExpansions
{
	[BepInPlugin("Endskill.XpExpansions", "XpExpansions", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BepinExLoader : BasePlugin
	{
		public const string MODNAME = "XpExpansions";

		public const string AUTHOR = "Endskill";

		public const string GUID = "Endskill.XpExpansions";

		public const string VERSION = "1.0.0";

		public override void Load()
		{
			LogManager.SetLogger(((BasePlugin)this).Log);
			LogManager._debugMessagesActive = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.").Value;
			ClassInjector.RegisterTypeInIl2Cpp<ClientSidedBioTrackerAbility>();
			CacheApi.SaveInstance<ExpansionManager>(new ExpansionManager(), CacheApiWrapper.ExtensionCacheName);
		}
	}
}
namespace XpExpansions.Scripts
{
	public class ClientSidedBioTrackerAbility : MonoBehaviour
	{
		private float _nextUpdate = 0f;

		public ClientSidedBioTrackerAbility(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public void Update()
		{
			if (!(Time.time > _nextUpdate))
			{
				return;
			}
			if (GameStateManager.IsInExpedition)
			{
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				Enumerator<EnemyAgent> enumerator = AIG_CourseGraph.GetReachableEnemiesInNodes(((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode, 1).GetEnumerator();
				while (enumerator.MoveNext())
				{
					EnemyAgent current = enumerator.Current;
					ToolSyncManager.WantToTagEnemy(current);
				}
			}
			_nextUpdate = Time.time + 10f;
		}
	}
}
namespace XpExpansions.Patches
{
	[HarmonyBefore(new string[] { "Endskill.XpExpansions", "Endskill.GTFuckingXP" })]
	[HarmonyPatch(typeof(Dam_EnemyDamageBase))]
	public class EnemyDamageBasePatches
	{
		[HarmonyPatch("MeleeDamage")]
		[HarmonyPrefix]
		public static bool MeleePrefix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent)
		{
			return true;
		}
	}
}
namespace XpExpansions.Manager
{
	public abstract class BaseManager
	{
		private static string? _folderPath;

		protected string FolderPath
		{
			get
			{
				if (string.IsNullOrEmpty(_folderPath))
				{
					_folderPath = CacheApiWrapper.GetFolderPath();
				}
				return _folderPath;
			}
		}

		public abstract void LevelReached(Level level);

		public virtual void LevelInitialized(Level level)
		{
		}

		public virtual void Initialize()
		{
		}

		public virtual void LevelCleanup()
		{
		}
	}
	public class ClientSidedBioTrackerManager : BaseManager
	{
		private const string _expansionFileName = "BioTracker.json";

		public ClientSidedBioTrackerManager()
		{
			LevelApi.AddEndLevelCallback((Action)DestroyBioTrackerAbility);
		}

		public override void Initialize()
		{
			WriteDefaultJsonBlocks();
			UpdateEverything();
		}

		public override void LevelReached(Level level)
		{
			LevelLayout levelLayout = CacheApiWrapper.GetCurrentLevelLayout();
			List<LocalBioTrackerData> instance = CacheApi.GetInstance<List<LocalBioTrackerData>>(CacheApiWrapper.ExtensionCacheName);
			LocalBioTrackerData localBioTrackerData = instance.FirstOrDefault((LocalBioTrackerData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId);
			if (localBioTrackerData != null)
			{
				if (localBioTrackerData.UnlockAtLevel <= level.LevelNumber)
				{
					CacheApiWrapper.DestroyOldCreateRegisterAndReturnComponent<ClientSidedBioTrackerAbility>();
				}
				else
				{
					DestroyBioTrackerAbility();
				}
			}
		}

		public void DestroyBioTrackerAbility()
		{
			CacheApiWrapper.KillScript<ClientSidedBioTrackerAbility>();
		}

		private void WriteDefaultJsonBlocks()
		{
			if (!Directory.Exists(base.FolderPath))
			{
				Directory.CreateDirectory(base.FolderPath);
			}
			string path = Path.Combine(base.FolderPath, "BioTracker.json");
			if (!File.Exists(path))
			{
				JsonSerializerOptions options = new JsonSerializerOptions
				{
					IncludeFields = false,
					ReadCommentHandling = JsonCommentHandling.Skip,
					PropertyNameCaseInsensitive = true,
					WriteIndented = true
				};
				File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options));
			}
		}

		private void UpdateEverything()
		{
			CacheApi.SaveInstance<List<LocalBioTrackerData>>(JsonSerializer.Deserialize<List<LocalBioTrackerData>>(File.ReadAllText(Path.Combine(base.FolderPath, "BioTracker.json"))), CacheApiWrapper.ExtensionCacheName);
		}

		private List<LocalBioTrackerData> GetDefaultData()
		{
			List<LocalBioTrackerData> list = new List<LocalBioTrackerData>();
			for (int i = 0; i < 20; i++)
			{
				list.Add(new LocalBioTrackerData(i, 3));
			}
			return list;
		}
	}
	public class DeactivateManager : BaseManager
	{
		private const string _expansionFileName = "DeactivateOnMissions.json";

		private const string _expansionClassFileName = "DeactivateClassLayout.json";

		public override void Initialize()
		{
		}

		public override void LevelReached(Level level)
		{
		}

		private void WriteDefaultJsonBlocks()
		{
			if (!Directory.Exists(base.FolderPath))
			{
				Directory.CreateDirectory(base.FolderPath);
			}
			JsonSerializerOptions options = new JsonSerializerOptions
			{
				IncludeFields = false,
				ReadCommentHandling = JsonCommentHandling.Skip,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true
			};
			string path = Path.Combine(base.FolderPath, "DeactivateOnMissions.json");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, JsonSerializer.Serialize(new List<int> { 69420, 42069 }, options));
			}
		}
	}
	public class DoubleJumpManager : BaseManager
	{
		public const string DoubleJumpXpExpansionId = "Endskill.DoubleJumpExpansion";

		private const string _expansionFileName = "DoubleJumpExpansion.json";

		private bool _harmonyState;

		public Harmony DoubleJumpHarmonyAbility { get; private set; }

		public DoubleJumpManager()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			DoubleJumpHarmonyAbility = new Harmony("Endskill.DoubleJumpExpansion");
			Harmony.UnpatchID("com.mccad00.DoubleJump");
			_harmonyState = false;
		}

		public override void Initialize()
		{
			WriteDefaultJsonBlocks();
			UpdateEverything();
		}

		public override void LevelCleanup()
		{
			if (_harmonyState)
			{
				DoubleJumpHarmonyAbility.UnpatchSelf();
				_harmonyState = false;
			}
		}

		public override void LevelReached(Level level)
		{
			LogManager.Message("LevelReached, DoubleJump " + ((object)level).ToString());
			LevelLayout levelLayout = CacheApiWrapper.GetCurrentLevelLayout();
			List<DoubleJumpData> instance = CacheApi.GetInstance<List<DoubleJumpData>>(CacheApiWrapper.ExtensionCacheName);
			DoubleJumpData doubleJumpData = instance.FirstOrDefault((DoubleJumpData it) => it.LevelLayoutPersistentId == levelLayout.PersistentId);
			if (doubleJumpData != null)
			{
				if (doubleJumpData.UnlockAtLevel <= level.LevelNumber)
				{
					if (!_harmonyState)
					{
						Assembly assembly = Assembly.GetAssembly(typeof(EntryPoint));
						DoubleJumpHarmonyAbility.PatchAll(assembly);
						_harmonyState = true;
					}
				}
				else if (_harmonyState)
				{
					DoubleJumpHarmonyAbility.UnpatchSelf();
					_harmonyState = false;
				}
			}
			else if (_harmonyState)
			{
				DoubleJumpHarmonyAbility.UnpatchSelf();
				_harmonyState = false;
			}
		}

		private void WriteDefaultJsonBlocks()
		{
			if (!Directory.Exists(base.FolderPath))
			{
				Directory.CreateDirectory(base.FolderPath);
			}
			string path = Path.Combine(base.FolderPath, "DoubleJumpExpansion.json");
			if (!File.Exists(path))
			{
				JsonSerializerOptions options = new JsonSerializerOptions
				{
					IncludeFields = false,
					ReadCommentHandling = JsonCommentHandling.Skip,
					PropertyNameCaseInsensitive = true,
					WriteIndented = true
				};
				File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options));
			}
		}

		private void UpdateEverything()
		{
			CacheApi.SaveInstance<List<DoubleJumpData>>(JsonSerializer.Deserialize<List<DoubleJumpData>>(File.ReadAllText(Path.Combine(base.FolderPath, "DoubleJumpExpansion.json"))), CacheApiWrapper.ExtensionCacheName);
		}

		private List<DoubleJumpData> GetDefaultData()
		{
			List<DoubleJumpData> list = new List<DoubleJumpData>();
			for (int i = 0; i < 20; i++)
			{
				list.Add(new DoubleJumpData(i, 3));
			}
			return list;
		}
	}
	public class ExpansionManager : BaseManager
	{
		public const string ExpansionActivePath = "ExpansionsActive.json";

		public ExpansionManager()
		{
			LogManager.Message("ExpansionManager constructor.");
			InitApi.AddInitCallback((Action)Initialize);
			LevelApi.AddEndLevelCallback((Action)LevelCleanup);
			XpApi.AddOnLevelUpCallback((Action<Level>)LevelReached);
			XpApi.AddScriptsLoaded((Action<Level>)LevelInitialized);
		}

		public override void Initialize()
		{
			CacheApiWrapper.SetFolderPath(Path.Combine(ScriptManager.Instance.GetFolderPath(), "Expansions"));
			WriteDefaultData();
			List<BaseManager> list = CreateManagers();
			CacheApi.SaveInstance<List<BaseManager>>(list, CacheApiWrapper.ExtensionCacheName);
			foreach (BaseManager item in list)
			{
				item.Initialize();
			}
		}

		public override void LevelCleanup()
		{
			List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName);
			foreach (BaseManager item in instance)
			{
				item.LevelCleanup();
			}
		}

		public override void LevelReached(Level level)
		{
			LogManager.Message("LevelReached in the Expansion Manager.");
			List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName);
			foreach (BaseManager item in instance)
			{
				item.LevelReached(level);
			}
		}

		public override void LevelInitialized(Level level)
		{
			LogManager.Message("LevelInitialized in the Expansion Manager.");
			List<BaseManager> instance = CacheApi.GetInstance<List<BaseManager>>(CacheApiWrapper.ExtensionCacheName);
			foreach (BaseManager item in instance)
			{
				item.LevelInitialized(level);
			}
		}

		private List<BaseManager> CreateManagers()
		{
			List<BaseManager> list = new List<BaseManager>();
			string path = Path.Combine(base.FolderPath, "ExpansionsActive.json");
			ActiveExpansions activeExpansions = JsonSerializer.Deserialize<ActiveExpansions>(File.ReadAllText(path));
			LogManager.Debug("CreateManagers method.");
			if (activeExpansions != null)
			{
				if (activeExpansions.DoubleJumpAbility)
				{
					list.Add(new DoubleJumpManager());
				}
				if (activeExpansions.StartingXp)
				{
					list.Add(new StartingLevelXpManager());
				}
				if (activeExpansions.LivingBioAbility)
				{
					list.Add(new ClientSidedBioTrackerManager());
				}
			}
			return list;
		}

		private void WriteDefaultData()
		{
			if (!Directory.Exists(base.FolderPath))
			{
				Directory.CreateDirectory(base.FolderPath);
			}
			string path = Path.Combine(base.FolderPath, "ExpansionsActive.json");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, JsonSerializer.Serialize(new ActiveExpansions(startingXp: false, doubleJumpAbility: false)));
			}
		}
	}
	public class ExplosionAbilityManager : BaseManager
	{
		public const string ExplosionHarmonyInstanceId = "Endskill.ExplosionAbility";

		public Harmony ExplosionHarmony { get; private set; }

		public ExplosionAbilityManager()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			ExplosionHarmony = new Harmony("Endskill.ExplosionAbility");
		}

		public override void Initialize()
		{
		}

		public override void LevelReached(Level level)
		{
		}

		public override void LevelCleanup()
		{
		}
	}
	public static class LogManager
	{
		private static ManualLogSource logger;

		internal static bool _debugMessagesActive;

		internal static void SetLogger(ManualLogSource log)
		{
			logger = log;
		}

		public static void Verbose(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogInfo(msg);
			}
		}

		public static void Debug(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogDebug(msg);
			}
		}

		public static void Message(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogMessage(msg);
			}
		}

		public static void Error(object msg)
		{
			logger.LogError(msg);
		}

		public static void Warn(object msg)
		{
			logger.LogWarning(msg);
		}
	}
	internal class StartingLevelXpManager : BaseManager
	{
		private const string _expansionFileName = "StartingXP.json";

		public override void Initialize()
		{
			WriteDefaultJsonBlocks();
			UpdateEverything();
		}

		public override void LevelReached(Level level)
		{
		}

		public override void LevelInitialized(Level level)
		{
			ExpeditionInTierData expedition = RundownManager.ActiveExpedition;
			List<StartingXpData> instance = CacheApi.GetInstance<List<StartingXpData>>(CacheApiWrapper.ExtensionCacheName);
			StartingXpData startingXpData = instance.FirstOrDefault((StartingXpData it) => it.LevelLayoutData == expedition.LevelLayoutData);
			if (startingXpData != null)
			{
				XpApi.AddXp(startingXpData.StartingXp);
			}
		}

		private void UpdateEverything()
		{
			CacheApi.SaveInstance<List<StartingXpData>>(JsonSerializer.Deserialize<List<StartingXpData>>(File.ReadAllText(Path.Combine(base.FolderPath, "StartingXP.json"))), CacheApiWrapper.ExtensionCacheName);
		}

		private void WriteDefaultJsonBlocks()
		{
			if (!Directory.Exists(base.FolderPath))
			{
				Directory.CreateDirectory(base.FolderPath);
			}
			string path = Path.Combine(base.FolderPath, "StartingXP.json");
			if (!File.Exists(path))
			{
				JsonSerializerOptions options = new JsonSerializerOptions
				{
					IncludeFields = false,
					ReadCommentHandling = JsonCommentHandling.Skip,
					PropertyNameCaseInsensitive = true,
					WriteIndented = true
				};
				File.WriteAllText(path, JsonSerializer.Serialize(GetDefaultData(), options));
			}
		}

		private List<StartingXpData> GetDefaultData()
		{
			List<StartingXpData> list = new List<StartingXpData>();
			foreach (RundownDataBlock allBlock in GameDataBlockBase<RundownDataBlock>.GetAllBlocks())
			{
				Enumerator<ExpeditionInTierData> enumerator2 = allBlock.TierD.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					ExpeditionInTierData current2 = enumerator2.Current;
					list.Add(new StartingXpData(current2.LevelLayoutData, 100u));
				}
			}
			return list;
		}
	}
}
namespace XpExpansions.Information
{
	public class ActiveExpansions
	{
		public bool DoubleJumpAbility { get; set; }

		public bool StartingXp { get; set; }

		public bool LivingBioAbility { get; set; }

		public ActiveExpansions(bool startingXp, bool doubleJumpAbility)
		{
			DoubleJumpAbility = doubleJumpAbility;
			StartingXp = startingXp;
		}
	}
}
namespace XpExpansions.Information.StartingXp
{
	public class StartingXpData
	{
		public uint LevelLayoutData { get; set; }

		public uint StartingXp { get; set; }

		public StartingXpData(uint levelLayoutData, uint startingXp)
		{
			LevelLayoutData = levelLayoutData;
			StartingXp = startingXp;
		}
	}
}
namespace XpExpansions.Information.Explosion
{
	public class ExplosionAbilityData
	{
		public int LevelLayoutPersistentId { get; set; }

		public int UnlockAtLevel { get; set; }

		public ExplosionAbilityData(int levelLayoutPersistentId, int unlockAtLevel)
		{
			LevelLayoutPersistentId = levelLayoutPersistentId;
			UnlockAtLevel = unlockAtLevel;
		}
	}
}
namespace XpExpansions.Information.DoubleJump
{
	internal class DoubleJumpData
	{
		public int LevelLayoutPersistentId { get; set; }

		public int UnlockAtLevel { get; set; }

		public DoubleJumpData(int levelLayoutPersistentId, int unlockAtLevel)
		{
			LevelLayoutPersistentId = levelLayoutPersistentId;
			UnlockAtLevel = unlockAtLevel;
		}
	}
}
namespace XpExpansions.Information.BioTrackerLocal
{
	internal class LocalBioTrackerData
	{
		public int LevelLayoutPersistentId { get; set; }

		public int UnlockAtLevel { get; set; }

		public LocalBioTrackerData(int levelLayoutPersistentId, int unlockAtLevel)
		{
			LevelLayoutPersistentId = levelLayoutPersistentId;
			UnlockAtLevel = unlockAtLevel;
		}
	}
}
namespace XpExpansions.Extensions
{
	public static class CacheApiWrapper
	{
		internal static string ExtensionCacheName = "XpExtensions";

		private const string _folderPath = "FolderPath";

		public static void SetFolderPath(string path)
		{
			CacheApi.SaveInformation((object)"FolderPath", (object)path, ExtensionCacheName);
		}

		public static string GetFolderPath()
		{
			return CacheApi.GetInformation<string>((object)"FolderPath", ExtensionCacheName);
		}
	}
}

BepInEx/plugins/GTFO-API.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Resources;
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 AIGraph;
using AssetShards;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils;
using GTFO.API.Attributes;
using GTFO.API.Components;
using GTFO.API.Extensions;
using GTFO.API.Impl;
using GTFO.API.JSON;
using GTFO.API.JSON.Converters;
using GTFO.API.Native;
using GTFO.API.Resources;
using GTFO.API.Utilities;
using GTFO.API.Utilities.Impl;
using GTFO.API.Wrappers;
using GameData;
using Gear;
using Globals;
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.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using ItemSetup;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;
using UnityEngine.Analytics;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GTFO-API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.1")]
[assembly: AssemblyInformationalVersion("0.4.1+git1e8fe81-main")]
[assembly: AssemblyProduct("GTFO-API")]
[assembly: AssemblyTitle("GTFO-API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GTFO.API
{
	internal static class APILogger
	{
		private static readonly ManualLogSource _logger;

		static APILogger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_logger = new ManualLogSource("GTFO-API");
			Logger.Sources.Add((ILogSource)(object)_logger);
		}

		private static string Format(string module, object msg)
		{
			return $"[{module}]: {msg}";
		}

		public static void Info(string module, object data)
		{
			_logger.LogMessage((object)Format(module, data));
		}

		public static void Verbose(string module, object data)
		{
		}

		public static void Debug(string module, object data)
		{
			_logger.LogDebug((object)Format(module, data));
		}

		public static void Warn(string module, object data)
		{
			_logger.LogWarning((object)Format(module, data));
		}

		public static void Error(string module, object data)
		{
			_logger.LogError((object)Format(module, data));
		}
	}
	[API("Asset")]
	public static class AssetAPI
	{
		internal static ConcurrentDictionary<string, Object> s_RegistryCache = new ConcurrentDictionary<string, Object>();

		public static ApiStatusInfo Status => APIStatus.Asset;

		public static event Action OnStartupAssetsLoaded;

		public static event Action OnAssetBundlesLoaded;

		public static event Action OnImplReady;

		public static bool ContainsAsset(string assetName)
		{
			string text = assetName.ToUpper();
			if (!APIStatus.Asset.Ready)
			{
				return s_RegistryCache.ContainsKey(text);
			}
			return AssetShardManager.s_loadedAssetsLookup.ContainsKey(text);
		}

		public static Object GetLoadedAsset(string path)
		{
			string text = path.ToUpper();
			APILogger.Verbose("Asset", "Requested Asset: " + text);
			try
			{
				if (!APIStatus.Asset.Ready && s_RegistryCache.TryGetValue(text, out var value))
				{
					return value;
				}
				return AssetShardManager.GetLoadedAsset(text, false);
			}
			catch
			{
				return null;
			}
		}

		public static TAsset GetLoadedAsset<TAsset>(string path) where TAsset : Object
		{
			Object loadedAsset = GetLoadedAsset(path);
			if (loadedAsset == null)
			{
				return default(TAsset);
			}
			return ((Il2CppObjectBase)loadedAsset).Cast<TAsset>();
		}

		public static void RegisterAsset(string name, Object gameObject)
		{
			string text = name.ToUpper();
			if (!APIStatus.Asset.Ready)
			{
				if (s_RegistryCache.ContainsKey(text))
				{
					throw new ArgumentException("The asset with " + text + " has already been registered.", "name");
				}
				s_RegistryCache.TryAdd(text, gameObject);
			}
			else
			{
				AssetAPI_Impl.Instance.RegisterAsset(text, gameObject);
			}
		}

		public static void RegisterAssetBundle(AssetBundle bundle)
		{
			string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)bundle.AllAssetNames());
			APILogger.Verbose("Asset", "Bundle names: [" + string.Join(", ", array) + "]");
			string[] array2 = array;
			foreach (string text in array2)
			{
				Object val = bundle.LoadAsset(text);
				if (val != (Object)null)
				{
					RegisterAsset(text, val);
				}
				else
				{
					APILogger.Warn("Asset", "Skipping asset " + text);
				}
			}
		}

		public static void LoadAndRegisterAssetBundle(string pathToBundle)
		{
			AssetBundle obj = AssetBundle.LoadFromFile(pathToBundle);
			if ((Object)(object)obj == (Object)null)
			{
				throw new Exception("Failed to load asset bundle");
			}
			RegisterAssetBundle(obj);
		}

		public static void LoadAndRegisterAssetBundle(byte[] bundleBytes)
		{
			AssetBundle obj = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(bundleBytes));
			if ((Object)(object)obj == (Object)null)
			{
				throw new Exception("Failed to load asset bundle");
			}
			RegisterAssetBundle(obj);
		}

		public static Object InstantiateAsset(string assetName, string copyName)
		{
			if (ContainsAsset(copyName))
			{
				throw new ArgumentException("The asset you're trying to copy into is already registered", "copyName");
			}
			RegisterAsset(copyName, Object.Instantiate(GetLoadedAsset(assetName) ?? throw new ArgumentException("Couldn't find an asset with the name '" + assetName + "'", "assetName")));
			return GetLoadedAsset(copyName);
		}

		public static TAsset InstantiateAsset<TAsset>(string assetName, string copyName) where TAsset : Object
		{
			Object obj = InstantiateAsset(assetName, copyName);
			if (obj == null)
			{
				return default(TAsset);
			}
			return ((Il2CppObjectBase)obj).Cast<TAsset>();
		}

		public static bool TryInstantiateAsset<TAsset>(string assetName, string copyName, out TAsset clonedObj) where TAsset : Object
		{
			Object obj = InstantiateAsset(assetName, copyName);
			clonedObj = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<TAsset>() : default(TAsset));
			return (Object)(object)clonedObj != (Object)null;
		}

		private static void OnAssetsLoaded()
		{
			if (!APIStatus.Asset.Created)
			{
				APIStatus.CreateApi<AssetAPI_Impl>("Asset");
			}
			AssetAPI.OnStartupAssetsLoaded?.Invoke();
		}

		internal static void InvokeImplReady()
		{
			AssetAPI.OnImplReady?.Invoke();
		}

		internal static void Setup()
		{
			EventAPI.OnAssetsLoaded += OnAssetsLoaded;
			OnImplReady += LoadAssetBundles;
		}

		private static void LoadAssetBundles()
		{
			string assetBundlesDir = Path.Combine(Paths.BepInExRootPath, "Assets", "AssetBundles");
			string assetBundlesDir2 = Path.Combine(Paths.ConfigPath, "Assets", "AssetBundles");
			if (LoadAssetBundles(assetBundlesDir) | LoadAssetBundles(assetBundlesDir2, outdated: true))
			{
				AssetAPI.OnAssetBundlesLoaded?.Invoke();
			}
		}

		private static bool LoadAssetBundles(string assetBundlesDir, bool outdated = false)
		{
			if (outdated)
			{
				if (!Directory.Exists(assetBundlesDir))
				{
					return false;
				}
				APILogger.Warn("AssetAPI", "Storing asset bundles in the config path is deprecated and will be removed in a future version of GTFO-API. The path has been moved to 'BepInEx\\Assets\\AssetBundles'.");
			}
			if (!Directory.Exists(assetBundlesDir))
			{
				Directory.CreateDirectory(assetBundlesDir);
				return false;
			}
			string[] array = (from x in Directory.GetFiles(assetBundlesDir, "*", SearchOption.AllDirectories)
				where !x.EndsWith(".manifest", StringComparison.InvariantCultureIgnoreCase)
				select x).ToArray();
			if (array.Length == 0)
			{
				return false;
			}
			for (int i = 0; i < array.Length; i++)
			{
				try
				{
					LoadAndRegisterAssetBundle(array[i]);
				}
				catch (Exception ex)
				{
					APILogger.Warn("AssetAPI", $"Failed to load asset bundle '{array[i]}' ({ex.Message})");
				}
			}
			return true;
		}
	}
	[API("Event")]
	public static class EventAPI
	{
		public static ApiStatusInfo Status => APIStatus.Event;

		public static event Action OnManagersSetup;

		public static event Action OnExpeditionStarted;

		public static event Action OnAssetsLoaded;

		internal static void Setup()
		{
			Global.OnAllManagersSetup += Action.op_Implicit((Action)ManagersSetup);
			AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)AssetsLoaded);
			RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)ExpeditionStarted);
		}

		private static void ManagersSetup()
		{
			EventAPI.OnManagersSetup?.Invoke();
		}

		private static void ExpeditionStarted()
		{
			EventAPI.OnExpeditionStarted?.Invoke();
		}

		private static void AssetsLoaded()
		{
			EventAPI.OnAssetsLoaded?.Invoke();
		}
	}
	[API("GameData")]
	public class GameDataAPI
	{
		public static ApiStatusInfo Status => APIStatus.GameData;

		public static event Action OnGameDataInitialized;

		static GameDataAPI()
		{
			Status.Created = true;
			Status.Ready = true;
		}

		internal static void InvokeGameDataInit()
		{
			GameDataAPI.OnGameDataInitialized?.Invoke();
		}
	}
	[API("Il2Cpp")]
	public static class Il2CppAPI
	{
		public static ApiStatusInfo Status => APIStatus.Il2Cpp;

		static Il2CppAPI()
		{
			Status.Created = true;
			Status.Ready = true;
		}

		public unsafe static void InjectWithInterface<T>() where T : Il2CppObjectBase
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			List<INativeClassStruct> list = new List<INativeClassStruct>();
			foreach (Il2CppInterfaceAttribute item in GetCustomAttributesInType<T, Il2CppInterfaceAttribute>())
			{
				Il2CppClass* ptr = (Il2CppClass*)(void*)(IntPtr)typeof(Il2CppClassPointerStore<>).MakeGenericType(item.Type).GetField("NativeClassPtr").GetValue(null);
				IL2CPP.il2cpp_runtime_class_init((IntPtr)ptr);
				list.Add(UnityVersionHandler.Wrap(ptr));
			}
			RegisterTypeOptions val = new RegisterTypeOptions();
			val.set_LogSuccess(true);
			val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(list.ToArray()));
			ClassInjector.RegisterTypeInIl2Cpp<T>(val);
		}

		public unsafe static void* GetIl2CppMethod<T>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase
		{
			void** ptr = (void**)IL2CPP.GetIl2CppMethod(Il2CppClassPointerStore<T>.NativeClassPtr, isGeneric, methodName, returnTypeName, argTypes).ToPointer();
			if (ptr == null)
			{
				return ptr;
			}
			return *ptr;
		}

		public unsafe static TDelegate GetIl2CppMethod<T, TDelegate>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase where TDelegate : Delegate
		{
			void* il2CppMethod = GetIl2CppMethod<T>(methodName, returnTypeName, isGeneric, argTypes);
			if (il2CppMethod == null)
			{
				return null;
			}
			return Marshal.GetDelegateForFunctionPointer<TDelegate>((IntPtr)il2CppMethod);
		}

		public unsafe static INativeDetour CreateGenericDetour<TClass, TDelegate>(string methodName, string returnType, string[] paramTypes, Type[] genericArguments, TDelegate to, out TDelegate original) where TClass : Object where TDelegate : Delegate
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			IntPtr nativeClassPtr = Il2CppClassPointerStore<TClass>.NativeClassPtr;
			if (nativeClassPtr == IntPtr.Zero)
			{
				throw new ArgumentException(typeof(TClass).Name + " does not exist in il2cpp domain");
			}
			return INativeDetour.CreateAndApply<TDelegate>(UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)IL2CPP.il2cpp_method_get_from_reflection(((Il2CppObjectBase)new MethodInfo(IL2CPP.il2cpp_method_get_object(IL2CPP.GetIl2CppMethod(nativeClassPtr, true, methodName, returnType, paramTypes), nativeClassPtr)).MakeGenericMethod(((IEnumerable<Type>)genericArguments).Select((Func<Type, Type>)Il2CppType.From).ToArray())).Pointer)).MethodPointer, to, ref original);
		}

		private static IEnumerable<TAttribute> GetCustomAttributesInType<T, TAttribute>() where TAttribute : Attribute
		{
			Type attributeType = typeof(TAttribute);
			return typeof(T).GetCustomAttributes(attributeType, inherit: true).Union(typeof(T).GetInterfaces().SelectMany((Type interfaceType) => interfaceType.GetCustomAttributes(attributeType, inherit: true))).Distinct()
				.Cast<TAttribute>();
		}
	}
	public delegate void LevelDataUpdateEvent(ActiveExpedition activeExp, ExpeditionInTierData expData);
	public delegate void LevelSelectedEvent(eRundownTier expTier, int expIndexInTier, ExpeditionInTierData expData);
	[API("Level")]
	public static class LevelAPI
	{
		private static eRundownTier s_LatestExpTier = (eRundownTier)99;

		private static int s_LatestExpIndex = -1;

		public static ApiStatusInfo Status => APIStatus.Level;

		public static event LevelDataUpdateEvent OnLevelDataUpdated;

		public static event LevelSelectedEvent OnLevelSelected;

		public static event Action OnBuildStart;

		public static event Action OnBuildDone;

		public static event Action OnEnterLevel;

		public static event Action OnLevelCleanup;

		internal static void Setup()
		{
			Status.Created = true;
			Status.Ready = true;
			EventAPI.OnExpeditionStarted += EnterLevel;
		}

		internal static void ExpeditionUpdated(pActiveExpedition activeExp, ExpeditionInTierData expData)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			LevelAPI.OnLevelDataUpdated?.Invoke(ActiveExpedition.CreateFrom(activeExp), expData);
			eRundownTier tier = activeExp.tier;
			int expeditionIndex = activeExp.expeditionIndex;
			if (tier != s_LatestExpTier || expeditionIndex != s_LatestExpIndex)
			{
				LevelAPI.OnLevelSelected?.Invoke(tier, expeditionIndex, expData);
				s_LatestExpTier = tier;
				s_LatestExpIndex = expeditionIndex;
			}
		}

		internal static void BuildStart()
		{
			LevelAPI.OnBuildStart?.Invoke();
		}

		internal static void BuildDone()
		{
			LevelAPI.OnBuildDone?.Invoke();
		}

		internal static void EnterLevel()
		{
			LevelAPI.OnEnterLevel?.Invoke();
		}

		internal static void LevelCleanup()
		{
			LevelAPI.OnLevelCleanup?.Invoke();
		}
	}
	public struct ActiveExpedition
	{
		public pPlayer player;

		public eRundownKey rundownType;

		public string rundownKey;

		public eRundownTier tier;

		public int expeditionIndex;

		public int hostIDSeed;

		public int sessionSeed;

		public static ActiveExpedition CreateFrom(pActiveExpedition pActiveExp)
		{
			ActiveExpedition result = default(ActiveExpedition);
			result.CopyFrom(pActiveExp);
			return result;
		}

		public void CopyFrom(pActiveExpedition pActiveExp)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			player = pActiveExp.player;
			rundownType = pActiveExp.rundownType;
			rundownKey = pActiveExp.rundownKey.data;
			tier = pActiveExp.tier;
			expeditionIndex = pActiveExp.expeditionIndex;
			hostIDSeed = pActiveExp.hostIDSeed;
			sessionSeed = pActiveExp.sessionSeed;
		}
	}
	[API("Localization")]
	public static class LocalizationAPI
	{
		private sealed class Entry
		{
			private readonly string?[] m_ValuesByLanguage = new string[12];

			private TextDBOptions m_Options;

			public uint? TextBlockId { get; private set; }

			private bool TryGetStringInAnyLanguage([NotNullWhen(true)] out string? value)
			{
				for (int i = 0; i < m_ValuesByLanguage.Length; i++)
				{
					value = m_ValuesByLanguage[i];
					if (value != null)
					{
						return true;
					}
				}
				value = null;
				return false;
			}

			private bool TryGetStringInLanguage(Language language, [NotNullWhen(true)] out string? value)
			{
				//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_0004: Expected I4, but got Unknown
				int num = language - 1;
				value = m_ValuesByLanguage[num];
				return value != null;
			}

			public bool TryGetString(Language language, FallbackValueOptions options, [NotNullWhen(true)] out string? value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetStringInLanguage(language, out value))
				{
					return true;
				}
				if (options.UseFallbackLanguage && TryGetStringInLanguage(options.FallbackLanguage.Value, out value))
				{
					return true;
				}
				if (options.UseAnyLanguage && TryGetStringInAnyLanguage(out value))
				{
					return true;
				}
				value = null;
				return false;
			}

			private string GetStringForTextDB(Language language, string key, FallbackValueOptions options)
			{
				//IL_0001: 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)
				if (TryGetString(language, options, out string value))
				{
					return value;
				}
				ValidateUseKey(key, language, options, "GenerateTextDB");
				return key;
			}

			[MemberNotNull("TextBlockId")]
			public void GenerateTextDataBlock(string key, TextDBOptions options, bool force = false)
			{
				m_Options = options;
				GenerateTextDataBlock(key, force);
			}

			[MemberNotNull("TextBlockId")]
			public void GenerateTextDataBlock(string key, bool force = false)
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Expected O, but got Unknown
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Expected O, but got Unknown
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_018d: Expected O, but got Unknown
				//IL_018e: Expected O, but got Unknown
				if (!TextBlockId.HasValue || force)
				{
					FallbackValueOptions options = m_Options.FallbackOptions ?? FallbackValueOptions.AnyLangOrKey;
					TextDataBlock val = new TextDataBlock
					{
						CharacterMetaData = (m_Options.CharacterMetadataId ?? 1)
					};
					((GameDataBlockBase<TextDataBlock>)val).internalEnabled = true;
					val.ExportVersion = 1;
					val.ImportVersion = 1;
					val.Description = string.Empty;
					val.English = GetStringForTextDB((Language)1, key, options);
					val.French = LanguageData.op_Implicit(GetStringForTextDB((Language)2, key, options));
					val.Italian = LanguageData.op_Implicit(GetStringForTextDB((Language)3, key, options));
					val.German = LanguageData.op_Implicit(GetStringForTextDB((Language)4, key, options));
					val.Spanish = LanguageData.op_Implicit(GetStringForTextDB((Language)5, key, options));
					val.Russian = LanguageData.op_Implicit(GetStringForTextDB((Language)6, key, options));
					val.Portuguese_Brazil = LanguageData.op_Implicit(GetStringForTextDB((Language)7, key, options));
					val.Polish = LanguageData.op_Implicit(GetStringForTextDB((Language)8, key, options));
					val.Japanese = LanguageData.op_Implicit(GetStringForTextDB((Language)9, key, options));
					val.Korean = LanguageData.op_Implicit(GetStringForTextDB((Language)10, key, options));
					val.Chinese_Traditional = LanguageData.op_Implicit(GetStringForTextDB((Language)11, key, options));
					val.Chinese_Simplified = LanguageData.op_Implicit(GetStringForTextDB((Language)12, key, options));
					((GameDataBlockBase<TextDataBlock>)val).name = key;
					val.MachineTranslation = false;
					val.SkipLocalization = false;
					((GameDataBlockBase<TextDataBlock>)val).persistentID = 0u;
					TextDataBlock val2 = val;
					GameDataBlockBase<TextDataBlock>.AddBlock(val2, -1);
					TextBlockId = ((GameDataBlockBase<TextDataBlock>)(object)val2).persistentID;
				}
			}

			public bool TryGetString(Language language, string key, FallbackValueOptions options, out string? value)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetString(language, options, out value))
				{
					return true;
				}
				if (options.UseKey)
				{
					value = key;
					return true;
				}
				value = null;
				return false;
			}

			public string GetString(Language language, string key, FallbackValueOptions options)
			{
				//IL_0001: 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)
				if (TryGetString(language, options, out string value))
				{
					return value;
				}
				ValidateUseKey(key, language, options, "GetString");
				return key;
			}

			public string FormatString(Language language, string key, FallbackValueOptions options, object?[] args)
			{
				//IL_0001: 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)
				if (TryGetString(language, options, out string value))
				{
					return string.Format(value, args);
				}
				ValidateUseKey(key, language, options, "FormatString");
				return key;
			}

			public bool HasValueInLanguage(Language language)
			{
				//IL_0000: 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_0013: Unknown result type (might be due to invalid IL or missing references)
				ValidateLanguage(language, "language");
				return m_ValuesByLanguage[language - 1] != null;
			}

			public void AddValue(Language language, string value, bool force = false)
			{
				//IL_000b: 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)
				//IL_000f: Expected I4, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				ArgumentNullException.ThrowIfNull(value, "value");
				int num = language - 1;
				if (num < 0 || num >= m_ValuesByLanguage.Length)
				{
					throw new ArgumentOutOfRangeException("language");
				}
				ref string reference = ref m_ValuesByLanguage[num];
				if (reference != null && !force)
				{
					return;
				}
				reference = value;
				if (TextBlockId.HasValue)
				{
					TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock(TextBlockId.Value);
					if (block != null)
					{
						UpdateTextDataBlock(block, language, reference);
					}
				}
			}
		}

		[Flags]
		public enum FallbackValueFlags
		{
			None = 0,
			FallbackLanguage = 1,
			AnyLanguage = 2,
			Key = 4,
			FallbackOrAnyLanguage = 3,
			FallbackLanguageOrKey = 5,
			AnyLanguageOrKey = 6,
			FallbackOrAnyLanguageOrKey = 7
		}

		public readonly struct FallbackValueOptions : IEquatable<FallbackValueOptions>
		{
			public static readonly FallbackValueOptions None = default(FallbackValueOptions);

			public static readonly FallbackValueOptions Key = new FallbackValueOptions(FallbackValueFlags.Key);

			public static readonly FallbackValueOptions AnyLang = new FallbackValueOptions(FallbackValueFlags.AnyLanguage);

			public static readonly FallbackValueOptions AnyLangOrKey = new FallbackValueOptions(FallbackValueFlags.AnyLanguageOrKey);

			public FallbackValueFlags Flags { get; }

			public Language? FallbackLanguage { get; }

			public bool UseKey => Flags.HasFlag(FallbackValueFlags.Key);

			[MemberNotNullWhen(true, "FallbackLanguage")]
			public bool UseFallbackLanguage
			{
				[MemberNotNullWhen(true, "FallbackLanguage")]
				get
				{
					return Flags.HasFlag(FallbackValueFlags.FallbackLanguage);
				}
			}

			public bool UseAnyLanguage => Flags.HasFlag(FallbackValueFlags.AnyLanguage);

			public FallbackValueOptions(FallbackValueFlags flags, Language? fallbackLanguage = null)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				if (flags.HasFlag(FallbackValueFlags.FallbackLanguage))
				{
					if (!fallbackLanguage.HasValue)
					{
						throw new ArgumentNullException("fallbackLanguage", "A fallback language is required if specifying the flag FallbackLanguage");
					}
					ValidateLanguage(fallbackLanguage.Value, "fallbackLanguage");
				}
				Flags = flags;
				FallbackLanguage = fallbackLanguage;
			}

			public override int GetHashCode()
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				return HashCode.Combine<FallbackValueFlags, Language>(Flags, FallbackLanguage.GetValueOrDefault());
			}

			public override bool Equals([NotNullWhen(true)] object? obj)
			{
				if (obj is FallbackValueOptions other)
				{
					return Equals(other);
				}
				return false;
			}

			public bool Equals(FallbackValueOptions other)
			{
				//IL_0020: 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)
				if (Flags == other.Flags)
				{
					return FallbackLanguage == other.FallbackLanguage;
				}
				return false;
			}

			public FallbackValueOptions IncludeKey()
			{
				return new FallbackValueOptions(Flags | FallbackValueFlags.Key, FallbackLanguage);
			}

			public FallbackValueOptions ExcludeKey()
			{
				return new FallbackValueOptions(Flags & ~FallbackValueFlags.Key, FallbackLanguage);
			}

			public FallbackValueOptions IncludeFallbackLanguage(Language language)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				ValidateLanguage(language, "language");
				return new FallbackValueOptions(Flags | FallbackValueFlags.FallbackLanguage, language);
			}

			public FallbackValueOptions ExcludeFallbackLanguage()
			{
				return new FallbackValueOptions(Flags & ~FallbackValueFlags.FallbackLanguage);
			}

			public FallbackValueOptions IncludeAnyLanguage()
			{
				return new FallbackValueOptions(Flags | FallbackValueFlags.AnyLanguage, FallbackLanguage);
			}

			public FallbackValueOptions ExcludeAnyLanguage()
			{
				return new FallbackValueOptions(Flags & ~FallbackValueFlags.AnyLanguage, FallbackLanguage);
			}

			public FallbackValueOptions Combine(FallbackValueOptions other)
			{
				return new FallbackValueOptions(Flags | other.Flags, FallbackLanguage ?? other.FallbackLanguage);
			}

			public static bool operator ==(FallbackValueOptions left, FallbackValueOptions right)
			{
				return left.Equals(right);
			}

			public static bool operator !=(FallbackValueOptions left, FallbackValueOptions right)
			{
				return !(left == right);
			}

			public static FallbackValueOptions FallbackLang(Language fallbackLanguage)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return new FallbackValueOptions(FallbackValueFlags.FallbackLanguage, fallbackLanguage);
			}

			public static FallbackValueOptions FallbackOrAnyLang(Language fallbackLanguage)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return new FallbackValueOptions(FallbackValueFlags.FallbackOrAnyLanguage, fallbackLanguage);
			}

			public static FallbackValueOptions FallbackLangOrKey(Language fallbackLanguage)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return new FallbackValueOptions(FallbackValueFlags.FallbackLanguageOrKey, fallbackLanguage);
			}

			public static FallbackValueOptions FallbackOrAnyLangOrKey(Language fallbackLanguage)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return new FallbackValueOptions(FallbackValueFlags.FallbackOrAnyLanguageOrKey, fallbackLanguage);
			}
		}

		public struct TextDBOptions
		{
			private FallbackValueOptions? m_FallbackOptions;

			private uint? m_CharacterMetadataId;

			public uint? CharacterMetadataId
			{
				readonly get
				{
					return m_CharacterMetadataId;
				}
				set
				{
					m_CharacterMetadataId = value;
				}
			}

			public FallbackValueOptions? FallbackOptions
			{
				readonly get
				{
					return m_FallbackOptions;
				}
				set
				{
					m_FallbackOptions = value;
				}
			}
		}

		private static readonly Dictionary<string, Entry> s_Entries = new Dictionary<string, Entry>();

		private static readonly List<string> s_EntriesToGenerateTextDBs = new List<string>();

		private static bool s_GameDataInitialized = false;

		private static readonly string STR_NoValueFoundExceptionMsg = "No localization value exists for key '{1}' in language '{0}'.";

		private static readonly string STR_UseKeyGeneric = "{2}: No localization value exists for key '{1}' in language '{0}', defaulting to key.";

		public static ApiStatusInfo Status => APIStatus.Localization;

		public static Language CurrentLanguage => Text.TextLocalizationService.CurrentLanguage;

		public static event Action? OnLanguageChange;

		internal static void Setup()
		{
			GameDataAPI.OnGameDataInitialized += OnGameDataInitialized;
			EventAPI.OnAssetsLoaded += OnGameAssetsLoaded;
			Status.Created = true;
		}

		internal static void OnGameDataInitialized()
		{
			s_GameDataInitialized = true;
			foreach (string s_EntriesToGenerateTextDB in s_EntriesToGenerateTextDBs)
			{
				if (s_Entries.TryGetValue(s_EntriesToGenerateTextDB, out Entry value))
				{
					value.GenerateTextDataBlock(s_EntriesToGenerateTextDB, force: true);
				}
			}
		}

		internal static void OnGameAssetsLoaded()
		{
			Status.Ready = true;
		}

		internal static void LanguageChanged()
		{
			LocalizationAPI.OnLanguageChange?.Invoke();
		}

		public static string FormatString(string key, params object?[] args)
		{
			return FormatString(key, FallbackValueOptions.None, args);
		}

		public static string FormatString(string key, Language fallbackLanguage, params object?[] args)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return FormatString(key, FallbackValueOptions.FallbackLang(fallbackLanguage), args);
		}

		public static string FormatString(string key, FallbackValueOptions options, params object?[] args)
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			ValidateLocalizationKey(key, "key");
			Language currentLanguage = CurrentLanguage;
			if (!s_Entries.TryGetValue(key, out Entry value))
			{
				ValidateUseKey(key, currentLanguage, options, "FormatString");
				return key;
			}
			return value.FormatString(currentLanguage, key, options, args);
		}

		public static string GetString(string key)
		{
			return GetString(key, FallbackValueOptions.None);
		}

		public static string GetString(string key, Language fallbackLanguage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return GetString(key, FallbackValueOptions.FallbackLang(fallbackLanguage));
		}

		public static string GetString(string key, FallbackValueOptions options)
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			ValidateLocalizationKey(key, "key");
			Language currentLanguage = CurrentLanguage;
			if (!s_Entries.TryGetValue(key, out Entry value))
			{
				ValidateUseKey(key, currentLanguage, options, "GetString");
				return key;
			}
			return value.GetString(currentLanguage, key, options);
		}

		public static bool TryGetString(string key, [NotNullWhen(true)] out string? value)
		{
			return TryGetString(key, FallbackValueOptions.None, out value);
		}

		public static bool TryGetString(string key, Language fallbackLanguage, [NotNullWhen(true)] out string? value)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return TryGetString(key, FallbackValueOptions.FallbackLang(fallbackLanguage), out value);
		}

		public static bool TryGetString(string key, FallbackValueOptions options, [NotNullWhen(true)] out string? value)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			ValidateLocalizationKey(key, "key");
			if (!s_Entries.TryGetValue(key, out Entry value2))
			{
				if (options.UseKey)
				{
					value = key;
					return false;
				}
				value = null;
				return false;
			}
			return value2.TryGetString(CurrentLanguage, key, options, out value);
		}

		public static bool HasKey([NotNullWhen(true)] string? key)
		{
			if (!string.IsNullOrWhiteSpace(key))
			{
				return s_Entries.ContainsKey(key);
			}
			return false;
		}

		public static bool HasLocalizedValue([NotNullWhen(true)] string? key, Language language)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrWhiteSpace(key) && s_Entries.TryGetValue(key, out Entry value))
			{
				return value.HasValueInLanguage(language);
			}
			return false;
		}

		public static uint GenerateTextBlock(string key, TextDBOptions? textDataBlockOptions = null)
		{
			ValidateLocalizationKey(key, "key");
			Entry entry = s_Entries[key];
			if (entry.TextBlockId.HasValue)
			{
				return entry.TextBlockId.Value;
			}
			if (textDataBlockOptions.HasValue)
			{
				entry.GenerateTextDataBlock(key, textDataBlockOptions.Value);
			}
			else
			{
				entry.GenerateTextDataBlock(key);
			}
			s_EntriesToGenerateTextDBs.Add(key);
			return entry.TextBlockId.Value;
		}

		public static bool TryGetTextBlockId(string key, out uint blockId)
		{
			ValidateLocalizationKey(key, "key");
			if (!s_Entries.TryGetValue(key, out Entry value) || !value.TextBlockId.HasValue)
			{
				blockId = 0u;
				return false;
			}
			blockId = value.TextBlockId.Value;
			return true;
		}

		public static void AddEntry(string key, Language language, string value, TextDBOptions? textDataBlockOptions = null)
		{
			//IL_000b: 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)
			ValidateLocalizationKey(key, "key");
			ValidateLanguage(language, "language");
			if (value == null)
			{
				value = string.Empty;
			}
			bool exists;
			ref Entry valueRefOrAddDefault = ref CollectionsMarshal.GetValueRefOrAddDefault(s_Entries, key, out exists);
			if (valueRefOrAddDefault == null)
			{
				valueRefOrAddDefault = new Entry();
			}
			valueRefOrAddDefault.AddValue(language, value);
			if (textDataBlockOptions.HasValue && !exists)
			{
				s_EntriesToGenerateTextDBs.Add(key);
				if (s_GameDataInitialized)
				{
					valueRefOrAddDefault.GenerateTextDataBlock(key, textDataBlockOptions.Value);
				}
			}
		}

		public static void LoadFromResources(string baseName, TextDBOptions? textDataBlockOptions = null)
		{
			LoadFromResources(baseName, Assembly.GetCallingAssembly(), textDataBlockOptions);
		}

		public static void LoadFromResources(string baseName, Assembly assembly, TextDBOptions? textDataBlockOptions = null)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			ResourceManager resourceManager = new ResourceManager(baseName, assembly);
			List<Exception> list = new List<Exception>();
			CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
			foreach (CultureInfo cultureInfo in cultures)
			{
				bool isNeutralCulture = cultureInfo.IsNeutralCulture;
				Language language = GetLanguage(cultureInfo);
				if ((int)language == 0)
				{
					continue;
				}
				ResourceSet resourceSet;
				try
				{
					resourceSet = resourceManager.GetResourceSet(cultureInfo, createIfNotExists: true, tryParents: true);
				}
				catch (MissingManifestResourceException)
				{
					continue;
				}
				catch (Exception item)
				{
					list.Add(item);
					continue;
				}
				if (resourceSet == null)
				{
					continue;
				}
				foreach (DictionaryEntry item2 in resourceSet)
				{
					if (!(item2.Key is string text) || !(item2.Value is string value))
					{
						continue;
					}
					bool exists;
					ref Entry valueRefOrAddDefault = ref CollectionsMarshal.GetValueRefOrAddDefault(s_Entries, text, out exists);
					if (valueRefOrAddDefault == null)
					{
						valueRefOrAddDefault = new Entry();
					}
					valueRefOrAddDefault.AddValue(language, value, isNeutralCulture);
					if (textDataBlockOptions.HasValue && !exists)
					{
						s_EntriesToGenerateTextDBs.Add(text);
						if (s_GameDataInitialized)
						{
							valueRefOrAddDefault.GenerateTextDataBlock(text, textDataBlockOptions.Value);
						}
					}
				}
			}
			resourceManager.ReleaseAllResources();
			if (list.Count > 0)
			{
				throw new AggregateException(list);
			}
		}

		private static void ValidateLocalizationKey([NotNull] string key, [CallerArgumentExpression("key")] string? paramName = null)
		{
			ArgumentNullException.ThrowIfNull(key, paramName);
			if (string.IsNullOrWhiteSpace(paramName))
			{
				throw new ArgumentException("Localization key cannot be empty/whitespace", paramName ?? "key");
			}
		}

		private static void ValidateLanguage(Language language, [CallerArgumentExpression("language")] string? paramName = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.IsDefined<Language>(language))
			{
				throw new ArgumentException($"'{language}' is not a valid language", paramName ?? "language");
			}
		}

		private static void ValidateUseKey(string key, Language language, FallbackValueOptions options, string useCategory)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!options.UseKey)
			{
				throw new KeyNotFoundException(string.Format(STR_NoValueFoundExceptionMsg, language, key));
			}
			APILogger.Warn("LocalizationAPI", string.Format(STR_UseKeyGeneric, language, key, useCategory));
		}

		private static Language GetLanguage(CultureInfo info)
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			while (!info.IsNeutralCulture)
			{
				info = info.Parent;
				if (string.IsNullOrEmpty(info.Name))
				{
					return (Language)0;
				}
			}
			return (Language)(info.Name switch
			{
				"en" => 1, 
				"fr" => 2, 
				"it" => 3, 
				"de" => 4, 
				"es" => 5, 
				"ru" => 6, 
				"pt" => 7, 
				"pl" => 8, 
				"ja" => 9, 
				"ko" => 10, 
				"zh-Hans" => 12, 
				"zh-Hant" => 11, 
				_ => 0, 
			});
		}

		private static void UpdateTextDataBlock(TextDataBlock block, Language language, string text)
		{
			//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_0038: Expected I4, but got Unknown
			switch (language - 1)
			{
			case 0:
				block.English = text;
				break;
			case 1:
				block.French = LanguageData.op_Implicit(text);
				break;
			case 2:
				block.Italian = LanguageData.op_Implicit(text);
				break;
			case 3:
				block.German = LanguageData.op_Implicit(text);
				break;
			case 4:
				block.Spanish = LanguageData.op_Implicit(text);
				break;
			case 5:
				block.Russian = LanguageData.op_Implicit(text);
				break;
			case 6:
				block.Portuguese_Brazil = LanguageData.op_Implicit(text);
				break;
			case 7:
				block.Polish = LanguageData.op_Implicit(text);
				break;
			case 8:
				block.Japanese = LanguageData.op_Implicit(text);
				break;
			case 9:
				block.Korean = LanguageData.op_Implicit(text);
				break;
			case 10:
				block.Chinese_Traditional = LanguageData.op_Implicit(text);
				break;
			case 11:
				block.Chinese_Simplified = LanguageData.op_Implicit(text);
				break;
			}
		}
	}
	[API("Network")]
	public static class NetworkAPI
	{
		internal class CachedEvent
		{
			public string EventName { get; set; }

			public Type PayloadType { get; set; }

			public object OnReceive { get; set; }

			public bool IsFreeSize { get; set; }
		}

		internal static ConcurrentDictionary<string, CachedEvent> s_EventCache = new ConcurrentDictionary<string, CachedEvent>();

		public static ApiStatusInfo Status => APIStatus.Network;

		public static bool IsEventRegistered(string eventName)
		{
			return NetworkAPI_Impl.Instance.EventExists(eventName);
		}

		public static void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
		{
			if (!APIStatus.Network.Ready)
			{
				if (s_EventCache.ContainsKey(eventName))
				{
					throw new ArgumentException("An event with the name " + eventName + " has already been registered.", "eventName");
				}
				s_EventCache.TryAdd(eventName, new CachedEvent
				{
					EventName = eventName,
					PayloadType = typeof(T),
					OnReceive = onReceive,
					IsFreeSize = false
				});
			}
			else
			{
				NetworkAPI_Impl.Instance.RegisterEvent(eventName, onReceive);
			}
		}

		public static void InvokeEvent<T>(string eventName, T payload, SNet_ChannelType channelType = 2) where T : struct
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val, val2, num);
		}

		public static void InvokeEvent<T>(string eventName, T payload, SNet_Player target, SNet_ChannelType channelType = 2) where T : struct
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, target);
		}

		public static void InvokeEvent<T>(string eventName, T payload, List<SNet_Player> targets, SNet_ChannelType channelType = 2) where T : struct
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, targets.ToIl2Cpp());
		}

		public static void RegisterFreeSizedEvent(string eventName, Action<ulong, byte[]> onReceiveBytes)
		{
			if (!APIStatus.Network.Ready)
			{
				if (s_EventCache.ContainsKey(eventName))
				{
					throw new ArgumentException("An event with the name " + eventName + " has already been registered.", "eventName");
				}
				s_EventCache.TryAdd(eventName, new CachedEvent
				{
					EventName = eventName,
					PayloadType = null,
					OnReceive = onReceiveBytes,
					IsFreeSize = true
				});
			}
			else
			{
				NetworkAPI_Impl.Instance.RegisterFreeSizedEvent(eventName, onReceiveBytes);
			}
		}

		public static void InvokeFreeSizedEvent(string eventName, byte[] payload, SNet_ChannelType channelType = 2)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val, val2, num);
		}

		public static void InvokeFreeSizedEvent(string eventName, byte[] payload, SNet_Player target, SNet_ChannelType channelType = 2)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, target);
		}

		public static void InvokeFreeSizedEvent(string eventName, byte[] payload, IEnumerable<SNet_Player> targets, SNet_ChannelType channelType = 2)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SNet_SendGroup val = default(SNet_SendGroup);
			SNet_SendQuality val2 = default(SNet_SendQuality);
			int num = default(int);
			SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
			SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, targets.ToList().ToIl2Cpp());
		}

		private static Il2CppStructArray<byte> MakeBytes<T>(string eventName, T payload) where T : struct
		{
			return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakePacketBytes(eventName, payload));
		}

		private static Il2CppStructArray<byte> MakeBytes(string eventName, byte[] payload)
		{
			return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakeFreeSizedPacketBytes(eventName, payload));
		}
	}
	[API("Prefab")]
	public static class PrefabAPI
	{
		private static Shader s_CustomGearShader;

		private static readonly Dictionary<uint, Action<SyringeFirstPerson>> s_SyringeActions = new Dictionary<uint, Action<SyringeFirstPerson>>();

		public static ApiStatusInfo Status => APIStatus.Prefab;

		private static Shader CustomGearShader
		{
			get
			{
				if ((Object)(object)s_CustomGearShader == (Object)null)
				{
					s_CustomGearShader = Shader.Find("Cell/Player/CustomGearShader");
				}
				return s_CustomGearShader;
			}
		}

		public static void CreateConsumable(string assetName, bool enableEmissive = false)
		{
			Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
			GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
			}
			ItemEquippable obj = val.AddComponent<ItemEquippable>();
			obj.m_isFirstPerson = false;
			((Item)obj).m_itemModelHolder = val.transform;
			ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null);
		}

		public static void CreateConsumablePickup(string assetName, bool enableEmissive = false)
		{
			Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
			GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
			}
			BoxCollider componentInChildren = val.GetComponentInChildren<BoxCollider>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				throw new Exception("The Consumable Pickup prefab doesn't contain a BoxCollider for interaction");
			}
			GameObject gameObject = ((Component)componentInChildren).gameObject;
			gameObject.layer = LayerMask.NameToLayer("Interaction");
			Interact_Pickup_PickupItem val2 = gameObject.AddComponent<Interact_Pickup_PickupItem>();
			((Interact_Base)val2).m_colliderToOwn = (Collider)(object)componentInChildren;
			ConsumablePickup_Core obj = val.AddComponent<ConsumablePickup_Core>();
			obj.m_syncComp = (Component)(object)val.AddComponent<LG_PickupItem_Sync>();
			obj.m_interactComp = (Component)(object)val2;
			ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null);
		}

		public static void CreateConsumableInstance<T>(string assetName) where T : ConsumableInstance
		{
			Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
			GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
			if ((Object)(object)obj == (Object)null)
			{
				throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
			}
			if (!ClassInjector.IsTypeRegisteredInIl2Cpp<T>())
			{
				ClassInjector.RegisterTypeInIl2Cpp<T>();
			}
			obj.layer = LayerMask.NameToLayer("Debris");
			Rigidbody component = obj.GetComponent<Rigidbody>();
			obj.AddComponent<ColliderMaterial>().PhysicsBody = component ?? throw new Exception("The Consumable Instance prefab doesn't contain a Rigidbody");
			obj.AddComponent<T>();
		}

		public static void CreateGearComponent(string assetName, bool enableEmissive = false)
		{
			Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
			GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
			if ((Object)(object)obj == (Object)null)
			{
				throw new ArgumentException("Couldnt find a game object asset with the name " + assetName, "assetName");
			}
			obj.layer = LayerMask.NameToLayer("FirstPersonItem");
			ReplaceShaderInAssetMaterials(obj, CustomGearShader, "ENABLE_FPS_RENDERING", enableEmissive ? "ENABLE_EMISSIVE" : null);
		}

		public static void CreateSyringe(uint itemPersistentId, Action<SyringeFirstPerson> onUse)
		{
			if (s_SyringeActions.ContainsKey(itemPersistentId))
			{
				throw new ArgumentException($"{itemPersistentId} is already registered with a syringe action.");
			}
			s_SyringeActions.Add(itemPersistentId, onUse);
		}

		internal static bool OnSyringeUsed(SyringeFirstPerson syringe)
		{
			if (s_SyringeActions.TryGetValue(((GameDataBlockBase<ItemDataBlock>)(object)((Item)syringe).ItemDataBlock).persistentID, out var value))
			{
				value(syringe);
				return true;
			}
			return false;
		}

		private static void ReplaceShaderInAssetMaterials(GameObject asset, Shader newShader, params string[] addedKeywords)
		{
			addedKeywords = addedKeywords.Where((string x) => !string.IsNullOrEmpty(x)).ToArray();
			foreach (MeshRenderer componentsInChild in asset.GetComponentsInChildren<MeshRenderer>(true))
			{
				foreach (Material item in (Il2CppArrayBase<Material>)(object)((Renderer)componentsInChild).materials)
				{
					item.shader = newShader;
					if (addedKeywords.Length != 0)
					{
						string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)item.shaderKeywords);
						int num = array.Length;
						Array.Resize(ref array, array.Length + addedKeywords.Length);
						for (int i = 0; i < addedKeywords.Length; i++)
						{
							array[num + i] = addedKeywords[i];
						}
						item.shaderKeywords = Il2CppStringArray.op_Implicit(array);
					}
				}
			}
		}
	}
	[API("SoundBank")]
	public static class SoundBankAPI
	{
		public static ApiStatusInfo Status => APIStatus.SoundBank;

		public static event Action OnSoundBanksLoaded;

		internal static void Setup()
		{
			EventAPI.OnManagersSetup += OnLoadSoundBanks;
		}

		private static void OnLoadSoundBanks()
		{
			FileInfo[] array = (from file in Directory.CreateDirectory(Path.Combine(Paths.BepInExRootPath, "Assets", "SoundBank")).EnumerateFiles()
				where file.Extension.Contains(".bnk")
				select file).ToArray();
			CollectionExtensions.Do<FileInfo>((IEnumerable<FileInfo>)array, (Action<FileInfo>)LoadBank);
			if (array.Any())
			{
				SoundBankAPI.OnSoundBanksLoaded?.Invoke();
			}
		}

		private unsafe static void LoadBank(FileInfo file)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			using FileStream fileStream = file.OpenRead();
			uint num = (uint)fileStream.Length;
			byte[] array = new byte[num];
			if (fileStream.Read(array, 0, (int)num) != 0)
			{
				void* intPtr = NativeMemory.AlignedAlloc(num, 16u);
				Unsafe.CopyBlock(ref Unsafe.AsRef<byte>(intPtr), ref array[0], num);
				uint value = default(uint);
				AKRESULT val = AkSoundEngine.LoadBank((IntPtr)(nint)intPtr, num, ref value);
				if ((int)val == 1)
				{
					APILogger.Info("SoundBankAPI", $"Loaded sound bank '{file.Name}' (bankId: {value:X2})");
				}
				else
				{
					APILogger.Error("SoundBankAPI", $"Error while loading sound bank '{file.Name}' ({val})");
				}
			}
		}
	}
	[BepInPlugin("dev.gtfomodding.gtfo-api", "GTFO-API", "0.4.1")]
	internal class EntryPoint : BasePlugin
	{
		private Harmony m_Harmony;

		public override void Load()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			APILogger.Verbose("Core", "Registering API Implementations");
			ClassInjector.RegisterTypeInIl2Cpp<NetworkAPI_Impl>();
			ClassInjector.RegisterTypeInIl2Cpp<AssetAPI_Impl>();
			APILogger.Verbose("Core", "Registering Wrappers");
			ClassInjector.RegisterTypeInIl2Cpp<ItemWrapped>();
			APILogger.Verbose("Core", "Registering Utilities Implementations");
			ClassInjector.RegisterTypeInIl2Cpp<ThreadDispatcher_Impl>();
			ClassInjector.RegisterTypeInIl2Cpp<CoroutineDispatcher_Impl>();
			APILogger.Verbose("Core", "Applying Patches");
			m_Harmony = new Harmony("dev.gtfomodding.gtfo-api");
			m_Harmony.PatchAll();
			EventAPI.Setup();
			AssetAPI.Setup();
			SoundBankAPI.Setup();
			LevelAPI.Setup();
			LocalizationAPI.Setup();
			APILogger.Verbose("Core", "Plugin Load Complete");
			APILogger.Warn("GTFO-API", "Syringes are currently disabled in this version");
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "GTFO.API";

		public const string Version = "0.4.1";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "git1e8fe81-main";

		public const string SemVer = "0.4.1+git1e8fe81-main";

		public const string GitRevShort = "1e8fe81";

		public const string GitRevLong = "1e8fe816dac645ea837fe046d35f0b1ec044f6db";

		public const string GitBranch = "main";

		public const string GitTag = "0.4.0";

		public const bool GitIsDirty = false;
	}
}
namespace GTFO.API.Wrappers
{
	public class ItemWrapped : Item
	{
		private static readonly Item__Get_pItemData Get_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Get_pItemData>("Get_pItemData", "Player.pItemData", isGeneric: false, Array.Empty<string>());

		private static readonly Item__Set_pItemData Set_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Set_pItemData>("Set_pItemData", "System.Void", isGeneric: false, new string[1] { "Player.pItemData" });

		private static readonly Item__GetCustomData GetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetCustomData>("GetCustomData", "Player.pItemData_Custom", isGeneric: false, Array.Empty<string>());

		private static readonly Item__SetCustomData SetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetCustomData>("SetCustomData", "System.Void", isGeneric: false, new string[2] { "Player.pItemData_Custom", "System.Boolean" });

		private static readonly Item__OnCustomDataUpdated OnCustomDataUpdatedBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnCustomDataUpdated>("OnCustomDataUpdated", "System.Void", isGeneric: false, new string[1] { "Player.pItemData_Custom" });

		private static readonly Item__Awake AwakeBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Awake>("Awake", "System.Void", isGeneric: false, Array.Empty<string>());

		private static readonly Item__OnDespawn OnDespawnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnDespawn>("OnDespawn", "System.Void", isGeneric: false, Array.Empty<string>());

		private static readonly Item__Setup SetupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Setup>("Setup", "System.Void", isGeneric: false, new string[1] { "GameData.ItemDataBlock" });

		private static readonly Item__OnGearSpawnComplete OnGearSpawnCompleteBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnGearSpawnComplete>("OnGearSpawnComplete", "System.Void", isGeneric: false, Array.Empty<string>());

		private static readonly Item__OnPickUp OnPickUpBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnPickUp>("OnPickUp", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SetupBaseModel SetupBaseModelBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetupBaseModel>("SetupBaseModel", "System.Void", isGeneric: false, new string[1] { "ItemSetup.ItemModelSetup" });

		private static readonly Item__SyncedTurnOn SyncedTurnOnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOn>("SyncedTurnOn", "System.Void", isGeneric: false, new string[2] { "Player.PlayerAgent", "AIGraph.AIG_CourseNode" });

		private static readonly Item__SyncedTurnOff SyncedTurnOffBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOff>("SyncedTurnOff", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SyncedTrigger SyncedTriggerBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTrigger>("SyncedTrigger", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SyncedTriggerSecondary SyncedTriggerSecondaryBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTriggerSecondary>("SyncedTriggerSecondary", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SyncedThrow SyncedThrowBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedThrow>("SyncedThrow", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SyncedPickup SyncedPickupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedPickup>("SyncedPickup", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });

		private static readonly Item__SyncedSetKeyValue SyncedSetKeyValueBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedSetKeyValue>("SyncedSetKeyValue", "System.Void", isGeneric: false, new string[2] { "System.Int32", "System.Single" });

		private static readonly Item__GetPickupInteraction GetPickupInteractionBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetPickupInteraction>("GetPickupInteraction", "Interact_Base", isGeneric: false, Array.Empty<string>());

		private static readonly Item__GetItem GetItemBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetItem>("GetItem", "Item", isGeneric: false, Array.Empty<string>());

		public ItemWrapped(IntPtr hdl)
			: base(hdl)
		{
		}

		public unsafe override pItemData Get_pItemData()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			pItemData* retstr = (pItemData*)stackalloc pItemData[1];
			return *Get_pItemDataBase(retstr, ((Il2CppObjectBase)this).Pointer.ToPointer());
		}

		public unsafe override void Set_pItemData(pItemData data)
		{
			Set_pItemDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &data);
		}

		public unsafe override pItemData_Custom GetCustomData()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return *GetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer());
		}

		public unsafe override void SetCustomData(pItemData_Custom custom, bool sync)
		{
			SetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &custom, sync);
		}

		public unsafe override void OnCustomDataUpdated(pItemData_Custom customDataCopy)
		{
			OnCustomDataUpdatedBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &customDataCopy);
		}

		public unsafe override void Awake()
		{
			AwakeBase(((Il2CppObjectBase)this).Pointer.ToPointer());
		}

		public unsafe override void OnDespawn()
		{
			OnDespawnBase(((Il2CppObjectBase)this).Pointer.ToPointer());
		}

		public unsafe override void Setup(ItemDataBlock data)
		{
			SetupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)data).Pointer.ToPointer());
		}

		public unsafe override void OnGearSpawnComplete()
		{
			OnGearSpawnCompleteBase(((Il2CppObjectBase)this).Pointer.ToPointer());
		}

		public unsafe override void OnPickUp(PlayerAgent player)
		{
			OnPickUpBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)player).Pointer.ToPointer());
		}

		public unsafe override void SetupBaseModel(ItemModelSetup setup)
		{
			SetupBaseModelBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)setup).Pointer.ToPointer());
		}

		public unsafe override void SyncedTurnOn(PlayerAgent agent, AIG_CourseNode courseNode)
		{
			SyncedTurnOnBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer(), ((Il2CppObjectBase)courseNode).Pointer.ToPointer());
		}

		public unsafe override void SyncedTurnOff(PlayerAgent agent)
		{
			SyncedTurnOffBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
		}

		public unsafe override void SyncedTrigger(PlayerAgent agent)
		{
			SyncedTriggerBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
		}

		public unsafe override void SyncedTriggerSecondary(PlayerAgent agent)
		{
			SyncedTriggerSecondaryBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
		}

		public unsafe override void SyncedThrow(PlayerAgent agent)
		{
			SyncedThrowBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
		}

		public unsafe override void SyncedPickup(PlayerAgent agent)
		{
			SyncedPickupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
		}

		public unsafe override void SyncedSetKeyValue(int key, float value)
		{
			SyncedSetKeyValueBase(((Il2CppObjectBase)this).Pointer.ToPointer(), key, value);
		}

		public unsafe override Interact_Base GetPickupInteraction()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			return new Interact_Base((IntPtr)GetPickupInteractionBase(((Il2CppObjectBase)this).Pointer.ToPointer()));
		}

		public unsafe override Item GetItem()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			return new Item((IntPtr)GetItemBase(((Il2CppObjectBase)this).Pointer.ToPointer()));
		}
	}
	public unsafe delegate pItemData* Item__Get_pItemData(pItemData* retstr, void* _this);
	public unsafe delegate void Item__Set_pItemData(void* _this, void* data);
	public unsafe delegate pItemData_Custom* Item__GetCustomData(void* _this);
	public unsafe delegate void Item__SetCustomData(void* _this, pItemData_Custom* custom, bool sync);
	public unsafe delegate void Item__OnCustomDataUpdated(void* _this, pItemData_Custom* customDataCopy);
	public unsafe delegate void Item__Awake(void* _this);
	public unsafe delegate void Item__OnDespawn(void* _this);
	public unsafe delegate void Item__Setup(void* _this, void* data);
	public unsafe delegate void Item__OnGearSpawnComplete(void* _this);
	public unsafe delegate void Item__OnPickUp(void* _this, void* player);
	public unsafe delegate void Item__SetupBaseModel(void* _this, void* setup);
	public unsafe delegate void Item__SyncedTurnOn(void* _this, void* agent, void* courseNode);
	public unsafe delegate void Item__SyncedTurnOff(void* _this, void* agent);
	public unsafe delegate void Item__SyncedTrigger(void* _this, void* agent);
	public unsafe delegate void Item__SyncedTriggerSecondary(void* _this, void* agent);
	public unsafe delegate void Item__SyncedThrow(void* _this, void* agent);
	public unsafe delegate void Item__SyncedPickup(void* _this, void* agent);
	public unsafe delegate void Item__SyncedSetKeyValue(void* _this, int key, float value);
	public unsafe delegate void* Item__GetPickupInteraction(void* _this);
	public unsafe delegate void* Item__GetItem(void* _this);
	[Il2CppInterface(typeof(iTerminalItem))]
	public interface iTerminalItemWrapper
	{
		uint TerminalItemId { get; set; }

		string TerminalItemKey { get; set; }

		string OverrideCode { get; set; }

		Vector3 LocatorBeaconPosition { get; set; }

		AIG_CourseNode SpawnNode { get; set; }

		bool ShowInFloorInventory { get; set; }

		string FloorItemLocation { get; set; }

		eFloorInventoryObjectType FloorItemType { get; set; }

		eFloorInventoryObjectStatus FloorItemStatus { get; set; }

		Func<List<string>, List<string>> OnWantDetailedInfo { get; set; }

		void Setup(string key);

		List<string> GetDetailedInfo(List<string> defaultDetails);

		void PlayPing();
	}
	[Il2CppInterface(typeof(iResourcePackReceiver))]
	public interface iResourcePackReceiverWrapper
	{
		bool IsLocallyOwned { get; }

		string InteractionName { get; }

		bool NeedHealth();

		bool NeedDisinfection();

		bool NeedWeaponAmmo();

		bool NeedToolAmmo();

		void GiveAmmoRel(float ammoStandardRel, float ammoSpecialRel, float ammoClassRel);

		void GiveHealth(float health);

		void GiveDisinfection(float disinfection);
	}
	[Il2CppInterface(typeof(iPlayerPingTarget))]
	public interface iPlayerPingTargetWrapper
	{
		eNavMarkerStyle PingTargetStyle { get; set; }
	}
	[Il2CppInterface(typeof(iWardenObjectiveItem))]
	public interface iWardenObjectiveItemWrapper
	{
		LG_LayerType OriginLayer { get; }

		AIG_CourseNode SpawnNode { get; }

		string PublicName { get; }

		Transform transform { get; }

		bool ObjectiveItemSolved { get; }

		ePickupItemStatus PickupItemStatus { get; }

		PlayerAgent PickedUpByPlayer { get; }

		void ActivateWardenObjectiveItem();

		void DeactivateWardenObjectiveItem();
	}
}
namespace GTFO.API.Utilities
{
	public static class CoroutineDispatcher
	{
		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			return CoroutineDispatcher_Impl.Instance.RunCoroutine(routine);
		}

		public static Coroutine StartInLevelCoroutine(IEnumerator routine)
		{
			return CoroutineDispatcher_Impl.Instance.RunInLevelCoroutine(routine);
		}
	}
	public delegate void LiveEditEventHandler(LiveEditEventArgs e);
	public class LiveEditEventArgs
	{
		public LiveEditEventType Type { get; set; }

		public string FullPath { get; set; }

		public string FileName { get; set; }
	}
	public enum LiveEditEventType
	{
		Created,
		Deleted,
		Renamed,
		Changed
	}
	public static class LiveEdit
	{
		internal const int RETRY_COUNT = 5;

		internal const float RETRY_INTERVAL = 0.1f;

		internal static readonly List<LiveEditListener> s_Listeners = new List<LiveEditListener>();

		public static LiveEditListener CreateListener(string path, string filter, bool includeSubDir)
		{
			LiveEditListener liveEditListener = new LiveEditListener(path, filter, includeSubDir);
			s_Listeners.Add(liveEditListener);
			return liveEditListener;
		}

		public static void TryReadFileContent(string filepath, Action<string> onReaded)
		{
			CoroutineDispatcher.StartCoroutine(GetFileStream(filepath, 5, 0.1f, delegate(FileStream stream)
			{
				try
				{
					using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
					onReaded?.Invoke(streamReader.ReadToEnd());
				}
				catch
				{
				}
			}));
		}

		private static IEnumerator GetFileStream(string filepath, int retryCount, float retryInterval, Action<FileStream> onFileStreamOpened)
		{
			retryCount = Math.Max(retryCount, 1);
			retryInterval = Math.Max(retryInterval, 0f);
			WaitForSecondsRealtime wait = new WaitForSecondsRealtime(retryInterval);
			for (int i = 0; i < retryCount; i++)
			{
				try
				{
					FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
					onFileStreamOpened?.Invoke(fileStream);
					fileStream.Close();
					break;
				}
				catch
				{
				}
				yield return wait;
			}
		}
	}
	public sealed class LiveEditListener : IDisposable
	{
		private FileSystemWatcher m_Watcher;

		private bool m_Allocated = true;

		private float m_ChangedCooldownTimer;

		public float FileChangedEventCooldown { get; set; } = 0.05f;


		public event LiveEditEventHandler FileChanged;

		public event LiveEditEventHandler FileDeleted;

		public event LiveEditEventHandler FileCreated;

		public event LiveEditEventHandler FileRenamed;

		private LiveEditListener()
		{
		}

		internal LiveEditListener(string path, string filter, bool includeSubDir)
		{
			LiveEditListener liveEditListener = this;
			m_Watcher = new FileSystemWatcher
			{
				Path = path,
				Filter = filter,
				IncludeSubdirectories = includeSubDir,
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime)
			};
			m_Watcher.Deleted += delegate(object sender, FileSystemEventArgs e)
			{
				FileSystemEventArgs e5 = e;
				ThreadDispatcher.Dispatch(delegate
				{
					liveEditListener.FileDeleted?.Invoke(CreateArgs(e5, LiveEditEventType.Deleted));
				});
			};
			m_Watcher.Created += delegate(object sender, FileSystemEventArgs e)
			{
				FileSystemEventArgs e4 = e;
				ThreadDispatcher.Dispatch(delegate
				{
					liveEditListener.FileCreated?.Invoke(CreateArgs(e4, LiveEditEventType.Created));
				});
			};
			m_Watcher.Renamed += delegate(object sender, RenamedEventArgs e)
			{
				RenamedEventArgs e3 = e;
				ThreadDispatcher.Dispatch(delegate
				{
					liveEditListener.FileRenamed?.Invoke(CreateArgs(e3, LiveEditEventType.Renamed));
				});
			};
			m_Watcher.Changed += delegate(object sender, FileSystemEventArgs e)
			{
				FileSystemEventArgs e2 = e;
				ThreadDispatcher.Dispatch(delegate
				{
					float time = Time.time;
					if (!(liveEditListener.m_ChangedCooldownTimer > time))
					{
						liveEditListener.m_ChangedCooldownTimer = time + liveEditListener.FileChangedEventCooldown;
						liveEditListener.FileChanged?.Invoke(CreateArgs(e2, LiveEditEventType.Changed));
					}
				});
			};
			m_Watcher.Error += delegate(object sender, ErrorEventArgs e)
			{
				APILogger.Error("LiveEdit", $"Path: {path} error reported! - {e.GetException()}");
			};
			StartListen();
		}

		private static LiveEditEventArgs CreateArgs(FileSystemEventArgs args, LiveEditEventType type)
		{
			return new LiveEditEventArgs
			{
				FullPath = args.FullPath,
				FileName = Path.GetFileName(args.FullPath),
				Type = type
			};
		}

		public void Dispose()
		{
			if (m_Allocated)
			{
				LiveEdit.s_Listeners.Remove(this);
				m_Allocated = false;
			}
			if (m_Watcher != null)
			{
				StopListen();
				this.FileChanged = null;
				this.FileDeleted = null;
				this.FileCreated = null;
				this.FileRenamed = null;
				m_Watcher.Dispose();
			}
			m_Watcher = null;
		}

		public void StopListen()
		{
			if (m_Watcher != null)
			{
				m_Watcher.EnableRaisingEvents = false;
			}
		}

		public void StartListen()
		{
			if (m_Watcher != null)
			{
				m_Watcher.EnableRaisingEvents = true;
			}
		}
	}
	internal static class MemoryUtils
	{
		private static byte[] _trampolineShellcode = new byte[12]
		{
			72, 184, 0, 0, 0, 0, 0, 0, 0, 0,
			255, 208
		};

		public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, string pattern, string mask, ulong sigOffset = 0uL)
		{
			return FindSignatureInBlock(block, blockSize, pattern.ToCharArray(), mask.ToCharArray(), sigOffset);
		}

		public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, char[] pattern, char[] mask, ulong sigOffset = 0uL)
		{
			for (ulong num = 0uL; num < blockSize; num++)
			{
				bool flag = true;
				for (uint num2 = 0u; num2 < mask.Length; num2++)
				{
					if (*(byte*)((long)num + (long)block + num2) != (byte)pattern[num2] && mask[num2] != '?')
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return (void*)((ulong)((long)num + (long)block) + sigOffset);
				}
			}
			return null;
		}

		public unsafe static byte[] MakeTrampoline(void* destination)
		{
			byte[] array = new byte[_trampolineShellcode.Length];
			Array.Copy(_trampolineShellcode, 0, array, 0, _trampolineShellcode.Length);
			fixed (byte* ptr = array)
			{
				*(long*)(ptr + 2) = (long)destination;
			}
			return array;
		}

		public unsafe static void CreateTrampolineBetween(void* start, void* end, void* destination)
		{
			ulong num = (ulong)end - (ulong)start;
			if (num < (ulong)_trampolineShellcode.Length)
			{
				throw new Exception("Trampoline block size is not enough to create.");
			}
			uint flNewProtect = default(uint);
			if (!Kernel32.VirtualProtect(start, num, 64u, &flNewProtect))
			{
				throw new Exception("Failed to change protection of trampoline block.");
			}
			APILogger.Verbose("MemoryUtils", "NOPing trampoline block");
			for (ulong num2 = 0uL; num2 < num; num2++)
			{
				*(sbyte*)((ulong)start + num2) = -112;
			}
			APILogger.Verbose("MemoryUtils", "Creating trampoline shellcode");
			byte[] array = MakeTrampoline(destination);
			APILogger.Verbose("MemoryUtils", "Writing trampoline shellcode");
			for (ulong num3 = 0uL; num3 < (ulong)array.Length; num3++)
			{
				*(byte*)((ulong)start + num3) = array[num3];
			}
			if (!Kernel32.VirtualProtect(start, num, flNewProtect, &flNewProtect))
			{
				throw new Exception("Failed to revert trampoline block protection.");
			}
		}
	}
	public class PersistentData<T> where T : PersistentData<T>, new()
	{
		private const string VERSION_REGEX = "\"PersistentDataVersion\": \"(.+?)\"";

		private static T s_CurrentData;

		public static T CurrentData
		{
			get
			{
				if (s_CurrentData != null)
				{
					return s_CurrentData;
				}
				s_CurrentData = Load();
				return s_CurrentData;
			}
			set
			{
				s_CurrentData = value;
			}
		}

		protected static string persistentPath => Path.Combine(Paths.BepInExRootPath, "GameData", "PersistentData", typeof(T).Assembly.GetName().Name, typeof(T).Name + ".json");

		public virtual string PersistentDataVersion { get; set; } = "1.0.0";


		public static T Load()
		{
			return Load(persistentPath);
		}

		public static T Load(string path)
		{
			T val = new T();
			if (File.Exists(path))
			{
				string text = File.ReadAllText(path);
				T val2;
				try
				{
					val2 = GTFO.API.JSON.JsonSerializer.Deserialize<T>(text);
				}
				catch (JsonException)
				{
					APILogger.Warn("JSON", "Failed to deserialize " + typeof(T).Name + ", replacing with default");
					string text2 = "FAILED";
					Match match = Regex.Match(text, "\"PersistentDataVersion\": \"(.+?)\"");
					if (match.Success)
					{
						text2 = match.Groups[1].Value + "-FAILED";
					}
					File.WriteAllText(Path.ChangeExtension(path, null) + "-" + text2 + ".json", text);
					val2 = new T();
					val2.Save(path);
				}
				if (val2.PersistentDataVersion != val.PersistentDataVersion)
				{
					val2.Save(Path.ChangeExtension(path, null) + "-" + val2.PersistentDataVersion + ".json");
					val.Save(path);
				}
				else
				{
					val = val2;
				}
			}
			else
			{
				val.Save(path);
			}
			return val;
		}

		public void Save()
		{
			Save(persistentPath);
		}

		public void Save(string path)
		{
			string contents = GTFO.API.JSON.JsonSerializer.Serialize((T)this);
			string directoryName = Path.GetDirectoryName(path);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllText(path, contents);
		}
	}
	public static class RegexUtils
	{
		private static readonly Regex s_VectorRegex = new Regex("-?[0-9.]+");

		public static bool TryParseVectorString(string input, out float[] vectorArray)
		{
			try
			{
				MatchCollection matchCollection = s_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;
			}
		}
	}
	public static class StringUtils
	{
		private static readonly uint[] _lookup32 = ((Func<uint[]>)delegate
		{
			uint[] array = new uint[256];
			for (int i = 0; i < 256; i++)
			{
				string text = i.ToString("X2");
				if (BitConverter.IsLittleEndian)
				{
					array[i] = text[0] + ((uint)text[1] << 16);
				}
				else
				{
					array[i] = text[1] + ((uint)text[0] << 16);
				}
			}
			return array;
		})();

		private unsafe static readonly uint* _lookup32Ptr = (uint*)(void*)GCHandle.Alloc(_lookup32, GCHandleType.Pinned).AddrOfPinnedObject();

		public unsafe static string FromByteArrayAsHex(byte[] bytes)
		{
			char[] array = new char[bytes.Length * 2];
			fixed (byte* ptr3 = bytes)
			{
				fixed (char* ptr = array)
				{
					uint* ptr2 = (uint*)ptr;
					for (int i = 0; i < bytes.Length; i++)
					{
						ptr2[i] = _lookup32Ptr[(int)ptr3[i]];
					}
				}
			}
			return new string(array);
		}
	}
	public static class ThreadDispatcher
	{
		public static void Dispatch(Action action)
		{
			ThreadDispatcher_Impl.Instance.EnqueueAction(action);
		}
	}
}
namespace GTFO.API.Utilities.Impl
{
	internal class CoroutineDispatcher_Impl : MonoBehaviour
	{
		private bool m_HasInLevelCoroutines;

		private readonly List<Coroutine> m_InLevelCoroutines;

		private static CoroutineDispatcher_Impl s_Instance;

		public static CoroutineDispatcher_Impl Instance
		{
			get
			{
				if ((Object)(object)s_Instance == (Object)null)
				{
					CoroutineDispatcher_Impl coroutineDispatcher_Impl = Object.FindObjectOfType<CoroutineDispatcher_Impl>();
					if ((Object)(object)coroutineDispatcher_Impl != (Object)null)
					{
						s_Instance = coroutineDispatcher_Impl;
					}
				}
				return s_Instance;
			}
		}

		static CoroutineDispatcher_Impl()
		{
			AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded;
		}

		private static void OnAssetsLoaded()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (!((Object)(object)s_Instance != (Object)null))
			{
				GameObject val = new GameObject();
				CoroutineDispatcher_Impl coroutineDispatcher_Impl = val.AddComponent<CoroutineDispatcher_Impl>();
				((Object)val).name = "GTFO-API Coroutine Dispatcher";
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)val);
				s_Instance = coroutineDispatcher_Impl;
			}
		}

		private void Update()
		{
			if (m_HasInLevelCoroutines && !GameStateManager.IsInExpedition)
			{
				m_InLevelCoroutines.ForEach(delegate(Coroutine coroutine)
				{
					((MonoBehaviour)this).StopCoroutine(coroutine);
				});
				m_HasInLevelCoroutines = false;
			}
		}

		[HideFromIl2Cpp]
		internal Coroutine RunCoroutine(IEnumerator routine)
		{
			return MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
		}

		[HideFromIl2Cpp]
		internal Coroutine RunInLevelCoroutine(IEnumerator routine)
		{
			if (!GameStateManager.IsInExpedition)
			{
				APILogger.Error("CoroutineDispatcher", "Cannot run InLevelCoroutine while you're not in level!");
				return null;
			}
			Coroutine val = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
			m_InLevelCoroutines.Add(val);
			m_HasInLevelCoroutines = true;
			return val;
		}
	}
	internal class ThreadDispatcher_Impl : MonoBehaviour
	{
		private readonly Queue<Action> s_ActionQueue = new Queue<Action>();

		private static ThreadDispatcher_Impl s_Instance;

		public static ThreadDispatcher_Impl Instance
		{
			get
			{
				if ((Object)(object)s_Instance == (Object)null)
				{
					ThreadDispatcher_Impl threadDispatcher_Impl = Object.FindObjectOfType<ThreadDispatcher_Impl>();
					if ((Object)(object)threadDispatcher_Impl != (Object)null)
					{
						s_Instance = threadDispatcher_Impl;
					}
				}
				return s_Instance;
			}
		}

		public ThreadDispatcher_Impl(IntPtr intPtr)
			: base(intPtr)
		{
		}

		static ThreadDispatcher_Impl()
		{
			AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded;
		}

		private static void OnAssetsLoaded()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (!((Object)(object)s_Instance != (Object)null))
			{
				GameObject val = new GameObject();
				ThreadDispatcher_Impl threadDispatcher_Impl = val.AddComponent<ThreadDispatcher_Impl>();
				((Object)val).name = "GTFO-API Thread Dispatcher";
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)val);
				s_Instance = threadDispatcher_Impl;
			}
		}

		[HideFromIl2Cpp]
		internal void EnqueueAction(Action action)
		{
			lock (s_ActionQueue)
			{
				s_ActionQueue.Enqueue(action);
			}
		}

		internal void Update()
		{
			lock (s_ActionQueue)
			{
				while (s_ActionQueue.Count > 0)
				{
					s_ActionQueue.Dequeue()?.Invoke();
				}
			}
		}
	}
}
namespace GTFO.API.Resources
{
	public class ApiStatusInfo
	{
		public bool Created { get; internal set; }

		public bool Ready { get; internal set; }
	}
	public static class APIStatus
	{
		private static GameObject s_ScriptHolder;

		public static ApiStatusInfo Asset { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Event { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo GameData { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Localization { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Il2Cpp { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Level { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Network { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo Prefab { get; internal set; } = new ApiStatusInfo();


		public static ApiStatusInfo SoundBank { get; internal set; } = new ApiStatusInfo();


		internal static GameObject ScriptHolder
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				if ((Object)(object)s_ScriptHolder == (Object)null)
				{
					s_ScriptHolder = new GameObject();
					((Object)s_ScriptHolder).name = "GTFO-API Script Holder";
					((Object)s_ScriptHolder).hideFlags = (HideFlags)61;
					Object.DontDestroyOnLoad((Object)(object)s_ScriptHolder);
				}
				return s_ScriptHolder;
			}
		}

		internal static void CreateApi<T>(string apiName) where T : Component
		{
			ApiStatusInfo apiStatusInfo = (ApiStatusInfo)(typeof(APIStatus).GetProperty(apiName)?.GetValue(null));
			if (apiStatusInfo == null)
			{
				throw new ArgumentException("Couldn't find API status for " + apiName, "apiName");
			}
			if (!apiStatusInfo.Created && !((Object)(object)ScriptHolder.GetComponent<T>() != (Object)null))
			{
				APILogger.Verbose("Core", "Creating API " + apiName);
				ScriptHolder.AddComponent<T>();
				apiStatusInfo.Created = true;
			}
		}
	}
	internal static class RuntimeData
	{
		public static Dictionary<InventorySlot, string[]> BotFavorites;
	}
	public static class ShaderConstants
	{
		public const string CUSTOM_GEAR_SHADER = "Cell/Player/CustomGearShader";
	}
	public static class NetworkConstants
	{
		public const string Magic = "GAPI_KSQK";

		public const byte MagicSize = 9;

		public const ulong VersionSignature = 18374688171108015565uL;
	}
}
namespace GTFO.API.Patches
{
	[HarmonyPatch(typeof(CellSettingsApply), "ApplyLanguage")]
	internal static class ApplyLanguage_Patches
	{
		private static bool s_LanguageChanged;

		[HarmonyWrapSafe]
		public static void Prefix(int value)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			s_LanguageChanged = (int)Text.TextLocalizationService.CurrentLanguage != value;
		}

		[HarmonyWrapSafe]
		public static void Postfix()
		{
			if (s_LanguageChanged)
			{
				LocalizationAPI.LanguageChanged();
			}
		}
	}
	[HarmonyPatch(typeof(AssetShardManager))]
	internal class AssetShardManager_Patches
	{
		[HarmonyPatch("Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		public static void Setup_Postfix()
		{
			if (!APIStatus.Asset.Created)
			{
				APIStatus.CreateApi<AssetAPI_Impl>("Asset");
			}
		}
	}
	[HarmonyPatch(typeof(Builder))]
	internal class Builder_Patches
	{
		[HarmonyPatch("Build")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void BuildStart_Postfix()
		{
			LevelAPI.BuildStart();
		}

		[HarmonyPatch("BuildDone")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void BuildDone_Postfix()
		{
			LevelAPI.BuildDone();
		}
	}
	[HarmonyPatch(typeof(GameDataInit))]
	internal class GameDataInit_Patches
	{
		private struct PluginWhitelistInfo
		{
			public string GUID;

			public string Name;

			public string Version;

			public string Checksum;
		}

		private static PluginWhitelistInfo[] FetchPluginWhitelist()
		{
			using HttpClient httpClient = new HttpClient();
			using Stream stream = httpClient.GetStreamAsync("https://raw.githubusercontent.com/GTFO-Modding/GTFO-API-PluginWhitelist/main/whitelist.txt").GetAwaiter().GetResult();
			using StreamReader streamReader = new StreamReader(stream);
			string[] array = streamReader.ReadToEnd().Split('\n', StringSplitOptions.RemoveEmptyEntries);
			PluginWhitelistInfo[] array2 = new PluginWhitelistInfo[array.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				string[] array3 = array[i].Split(":");
				array2[i] = new PluginWhitelistInfo
				{
					GUID = array3[0],
					Name = array3[1],
					Version = array3[2],
					Checksum = array3[3].TrimEnd('\r')
				};
			}
			return array2;
		}

		[HarmonyPatch("Initialize")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		public static void Initialize_Postfix()
		{
			Analytics.enabled = false;
			GameDataAPI.InvokeGameDataInit();
			if (!APIStatus.Network.Created)
			{
				APIStatus.CreateApi<NetworkAPI_Impl>("Network");
			}
		}

		private static void RemoveRequirementFromList(List<ExpeditionInTierData> list)
		{
			//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			Enumerator<ExpeditionInTierData> enumerator = list.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ExpeditionInTierData current = enumerator.Current;
				if (current.Enabled)
				{
					eExpeditionAccessibility accessibility = current.Accessibility;
					if ((int)accessibility == 0 || accessibility - 4 <= 1)
					{
						current.Accessibility = (eExpeditionAccessibility)2;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(GearManager))]
	internal static class GearManager_Patches
	{
		private unsafe delegate IntPtr ReadFromDiskDelegate(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo);

		private unsafe delegate void SaveToDiskDelegate(IntPtr path, IntPtr obj, Il2CppMethodInfo* methodInfo);

		private static bool m_PatchApplied;

		private static INativeDetour s_ReadFromDiskDetour;

		private static ReadFromDiskDelegate s_ReadFromDiskOriginal;

		private static INativeDetour s_SaveToDiskDetour;

		private static SaveToDiskDelegate s_SaveToDiskOriginal;

		private static string FavoritesDirectory => Path.Combine(Paths.BepInExRootPath, "GameData", "Favorites");

		private static string FavoritePath => Path.Combine(FavoritesDirectory, "Gear.json");

		private static string BotFavoritePath => Path.Combine(FavoritesDirectory, "BotGear.json");

		[HarmonyPatch("Setup")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private unsafe static void Setup_Prefix()
		{
			if (!m_PatchApplied)
			{
				if (!Directory.Exists(FavoritesDirectory))
				{
					Directory.CreateDirectory(FavoritesDirectory);
				}
				string methodName = "SaveToDisk";
				APILogger.Verbose("GearManager_Patches", "Applying ReadFromDisk Patch");
				s_ReadFromDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, ReadFromDiskDelegate>("ReadFromDisk", "T", new string[2]
				{
					typeof(string).FullName,
					typeof(bool).MakeByRefType().FullName
				}, new Type[1] { typeof(GearFavoritesData) }, (ReadFromDiskDelegate)Patch_ReadFromDisk, out s_ReadFromDiskOriginal);
				APILogger.Verbose("GearManager_Patches", "Applying SaveToDisk Patch");
				s_SaveToDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, SaveToDiskDelegate>(methodName, typeof(void).FullName, new string[2]
				{
					typeof(string).FullName,
					"T"
				}, new Type[1] { typeof(GearFavoritesData) }, (SaveToDiskDelegate)Patch_SaveToDisk, out s_SaveToDiskOriginal);
				m_PatchApplied = true;
			}
		}

		private unsafe static IntPtr Patch_ReadFromDisk(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			string text = String.op_Implicit(new String(path));
			if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase))
			{
				return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), createNew, methodInfo);
			}
			if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase))
			{
				return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), createNew, methodInfo);
			}
			return s_ReadFromDiskOriginal(path, createNew, methodInfo);
		}

		private unsafe static void Patch_SaveToDisk(IntPtr path, IntPtr favData, Il2CppMethodInfo* methodInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			string text = String.op_Implicit(new String(path));
			if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase))
			{
				s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), favData, methodInfo);
			}
			else if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase))
			{
				s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), favData, methodInfo);
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
			else
			{
				s_SaveToDiskOriginal(path, favData, methodInfo);
			}
		}
	}
	[HarmonyPatch(typeof(Global))]
	internal class Global_Patches
	{
		[HarmonyPatch("OnLevelCleanup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void LevelCleanup_Postfix()
		{
			LevelAPI.LevelCleanup();
		}
	}
	[HarmonyPatch(typeof(RundownManager))]
	internal class RundownManager_Patches
	{
		[HarmonyPatch("SetActiveExpedition")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetActiveExpedition_Postfix(pActiveExpedition expPackage, ExpeditionInTierData expTierData)
		{
			LevelAPI.ExpeditionUpdated(expPackage, expTierData);
		}
	}
	[HarmonyPatch(typeof(SNet_Replication))]
	internal class SNet_Replication_Patches
	{
		[HarmonyPatch("RecieveBytes")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		public static bool RecieveBytes_Prefix(Il2CppStructArray<byte> bytes, uint size, ulong messagerID)
		{
			if (size < 12)
			{
				return true;
			}
			byte[] array = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes);
			ushort num = BitConverter.ToUInt16(array, 0);
			if (NetworkAPI_Impl.Instance.m_ReplicatorKey == num)
			{
				string @string = Encoding.ASCII.GetString(array, 2, 9);
				if (@string != "GAPI_KSQK")
				{
					APILogger.Verbose("NetworkApi", $"Received invalid magic from {messagerID} ({@string} != {9}).");
					return true;
				}
				ulong num2 = BitConverter.ToUInt64(array, 11);
				if ((num2 & 0xFF00000000000000uL) != 18374686479671623680uL)
				{
					APILogger.Verbose("NetworkApi", $"Received invalid version signature from {messagerID}.");
					return true;
				}
				if (num2 != NetworkAPI_Impl.Instance.m_Signature)
				{
					APILogger.Error("NetworkApi", $"Received incompatible version signature, cannot unmask packet. Is {messagerID} on the same version?. ({num2} != {NetworkAPI_Impl.Instance.m_Signature})");
					return false;
				}
				ushort num3 = BitConverter.ToUInt16(array, 19);
				string string2 = Encoding.UTF8.GetString(array, 21, num3);
				if (!NetworkAPI.IsEventRegistered(string2))
				{
					APILogger.Error("NetworkApi", $"{messagerID} invoked an event {string2} which isn't registered.");
					return false;
				}
				NetworkAPI_Impl.Instance.HandlePacket(string2, messagerID, array, 21 + num3);
				return false;
			}
			return true;
		}
	}
}
namespace GTFO.API.Patches.Native
{
	internal class SyringeFirstPerson_Patch : NativePatch<SyringeFirstPerson_Patch.SyringeUsedDelegate>
	{
		[UnmanagedFunctionPointer(CallingConvention.FastCall)]
		public unsafe delegate eSyringeType SyringeUsedDelegate(void* pSyringe);

		public unsafe override void* MethodPtr => Il2CppAPI.GetIl2CppMethod<_ApplySyringe_d__18>("MoveNext", "System.Boolean", isGeneric: false, Array.Empty<string>());

		public override string JmpStartSig => "Æ\u0081\u00b4\0\0\0\u0001\u008b\u0087Ð\u0001\0\0\u0085À";

		public override string JmpStartMask => "xxxxxxxxxxxxxxx";

		public override byte[] CodeCave => new byte[10] { 198, 129, 180, 0, 0, 0, 1, 72, 137, 249 };

		public override uint TrampolineSize => 13u;

		public unsafe override SyringeUsedDelegate To => OnSyringeApplyEffect;

		public unsafe static eSyringeType OnSyringeApplyEffect(void* pSyringe)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			SyringeFirstPerson val = new SyringeFirstPerson(new IntPtr(pSyringe));
			if (PrefabAPI.OnSyringeUsed(val))
			{
				return (eSyringeType)(-1);
			}
			return val.m_type;
		}
	}
}
namespace GTFO.API.Native
{
	internal static class Kernel32
	{
		[DllImport("kernel32.dll")]
		public unsafe static extern void* VirtualAlloc(void* lpAddress, ulong dwSize, uint flAllocationType, uint flProtect);

		[DllImport("kernel32.dll")]
		public unsafe static extern bool VirtualProtect(void* lpAddress, ulong dwSize, uint flNewProtect, uint* lpflOldProtect);
	}
	internal static class MSVCRT
	{
		[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
		public unsafe static extern void* memcpy(void* destination, void* source, long num);
	}
	public abstract class NativePatch<T> where T : Delegate
	{
		private static readonly byte[] s_CodeCaveHeader = new byte[4] { 72, 131, 236, 40 };

		private static readonly byte[] s_CodeCaveFooter = new byte[17]
		{
			72, 184, 0, 0, 0, 0, 0, 0, 0, 0,
			255, 208, 72, 131,

BepInEx/plugins/GTFuckingXp.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
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 Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using EndskApi.Api;
using EndskApi.Enums.Menus;
using EndskApi.Information.EnemyKill;
using EndskApi.Information.Menus;
using EndskApi.Manager;
using EndskApi.Scripts;
using Enemies;
using FloatingTextAPI;
using GTFO.API;
using GTFuckingXP.Communication;
using GTFuckingXP.Enums;
using GTFuckingXP.Extensions;
using GTFuckingXP.Information;
using GTFuckingXP.Information.ClassSelector;
using GTFuckingXP.Information.Enemies;
using GTFuckingXP.Information.Level;
using GTFuckingXP.Information.NetworkingInfo;
using GTFuckingXP.Managers;
using GTFuckingXP.Patches;
using GTFuckingXP.Patches.SelectLevelPatches;
using GTFuckingXP.Scripts;
using GTFuckingXP.StolenCode;
using GTFuckingXp.Managers;
using GTFuckingXp.Patches;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TMPro;
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 = "")]
[assembly: AssemblyCompany("GTFuckingXp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitc03396b-dirty-master")]
[assembly: AssemblyProduct("GTFuckingXp")]
[assembly: AssemblyTitle("GTFuckingXp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace GTFuckingXp
{
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "GTFuckingXp";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gitc03396b-dirty-master";

		public const string SemVer = "1.0.0+gitc03396b-dirty-master";

		public const string GitRevShort = "c03396b-dirty";

		public const string GitRevLong = "c03396b43dd7f0dd7f6be64a74260c9045444f6f-dirty";

		public const string GitBranch = "master";

		public const string GitTag = null;

		public const bool GitIsDirty = true;
	}
}
namespace GTFuckingXp.Patches
{
	[HarmonyPatch(typeof(Dam_EnemyDamageBase))]
	public static class EnemyDamageBasePatches
	{
		[HarmonyPatch("MeleeDamage")]
		[HarmonyPrefix]
		public static void MeleePrefix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent)
		{
			if (((Agent)__instance.Owner).Alive && (Object)(object)sourceAgent != (Object)null && sourceAgent.IsLocallyOwned)
			{
				float num = dam;
				LogManager.Debug($"Melee damage from local player registered. {num} was scaled up to:");
				num *= CacheApiWrapper.GetActiveLevel().MeleeDamageMultiplier;
				LogManager.Debug($"{num}");
				dam = num;
			}
		}

		[HarmonyBefore(new string[] { "Endskill.GTFuckingXP", "com.dak.DamageNumbers" })]
		[HarmonyPatch("BulletDamage")]
		[HarmonyPrefix]
		public static void BulletPostfix(Dam_EnemyDamageBase __instance, ref float dam, Agent sourceAgent)
		{
			if (((Agent)__instance.Owner).Alive && (Object)(object)sourceAgent != (Object)null && sourceAgent.IsLocallyOwned)
			{
				float num = dam;
				LogManager.Debug($"Bullet damage from local player registered. {num} was scaled to:");
				num *= CacheApiWrapper.GetActiveLevel().WeaponDamageMultiplier;
				LogManager.Debug($"{num}");
				dam = num;
			}
		}
	}
}
namespace GTFuckingXp.Managers
{
	public static class EnemyKillManager
	{
		public static void Setup()
		{
			EnemyKillApi.AddEnemyKilledCallback((Action<EnemyKillDistribution>)EnemyKilled);
		}

		public static void EnemyKilled(EnemyKillDistribution info)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if ((int)info.lastHitType == 2)
			{
				GiveXpToEveryone(info.KilledEnemyAgent);
				return;
			}
			EnemyXp enemyXp = GetEnemyXp(info.KilledEnemyAgent);
			Vector3 position = info.KilledEnemyAgent.Position;
			position.y += 1f;
			Enumerator<SNet_Player> enumerator = SNet.LobbyPlayers.GetEnumerator();
			XpHandler xpHandler = default(XpHandler);
			while (enumerator.MoveNext())
			{
				SNet_Player current = enumerator.Current;
				if (current.IsBot)
				{
					continue;
				}
				if (info.LastHitDealtBy.Owner.PlayerSlot.index == current.PlayerSlot.index)
				{
					if (current.IsLocal)
					{
						if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
						{
							xpHandler.AddXp(enemyXp, position);
						}
					}
					else
					{
						NetworkApiXpManager.SendReceiveXp(current, enemyXp, position, forceDebuffXp: false);
					}
					continue;
				}
				float damageDealtBySnet = info.GetDamageDealtBySnet(current);
				if (damageDealtBySnet > 0.5f)
				{
					float num = damageDealtBySnet / ((Dam_SyncedDamageBase)info.KilledEnemyAgent.Damage).HealthMax;
					LogManager.Debug($"percentageDealt = {num} and damageDealt is {damageDealtBySnet}");
					NetworkApiXpManager.SendStaticXpInfo(current, (uint)((float)enemyXp.XpGain * num), (uint)((float)enemyXp.DebuffXp * num), (int)((float)enemyXp.LevelScalingXpDecrese * num), position);
				}
			}
		}

		private static void GiveXpToEveryone(EnemyAgent killedEnemy)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0045: 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)
			EnemyXp enemyXp = GetEnemyXp(killedEnemy);
			Vector3 position = killedEnemy.Position;
			position.y += 1f;
			XpHandler xpHandler = default(XpHandler);
			if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
			{
				xpHandler.AddXp(enemyXp, position, forceDebuffXp: true, "<#F30>");
			}
			NetworkApiXpManager.SendHalfAssedXp(enemyXp, position, forceDebuffXp: true);
		}

		private static EnemyXp GetEnemyXp(EnemyAgent killedEnemy)
		{
			EnemyAgent killedEnemy2 = killedEnemy;
			List<EnemyXp> instance = CacheApi.GetInstance<List<EnemyXp>>("GTF_XP");
			EnemyXp enemyXp = instance.FirstOrDefault((EnemyXp it) => it.EnemyId == killedEnemy2.EnemyDataID);
			if (enemyXp == null)
			{
				LogManager.Warn($"There was no enemy XP data found for {killedEnemy2.EnemyDataID}!");
				enemyXp = new EnemyXp(killedEnemy2.EnemyDataID, ((Object)killedEnemy2).name, 0u, 0u, 0);
				instance.Add(enemyXp);
				CacheApi.SaveInstance<List<EnemyXp>>(instance, "GTF_XP");
			}
			LogManager.Debug($"Enemy kill was registered. Enemy XpData was {enemyXp.XpGain}.");
			return enemyXp;
		}
	}
}
namespace GTFuckingXP.StolenCode
{
	public static class MtfoUtils
	{
		public static bool PluginExists;

		public static bool DataLoaded;

		public static string CustomPath { get; private set; }

		public static string Version { get; private set; }

		static MtfoUtils()
		{
			CustomPath = string.Empty;
			Version = string.Empty;
			PluginExists = false;
			DataLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info))
			{
				return;
			}
			PluginExists = true;
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => !x.IsDynamic && x.Location == info.Location);
				if (assembly == null)
				{
					throw new Exception("couldn't locate the MTFO assembly");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.FirstOrDefault((Type x) => x.Name == "ConfigManager");
				Type type2 = types.FirstOrDefault((Type x) => x.Name == "MTFO");
				if (type2 == null)
				{
					throw new Exception("couldn't locate MTFO's EntryPoint");
				}
				if (type == null)
				{
					throw new Exception("couldn't locate MTFO's ConfigManager");
				}
				FieldInfo field = type2.GetField("VERSION", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				if (field == null)
				{
					throw new Exception("couldn't locate MTFO's Version");
				}
				if (field2 == null)
				{
					throw new Exception("couldn't locate MTFO's CustomPath");
				}
				CustomPath = (string)field2.GetValue(null);
				Version = (string)field.GetValue(null);
				DataLoaded = true;
				Type type3 = types.FirstOrDefault((Type x) => x.Name == "HotReloader");
			}
			catch (Exception ex)
			{
				LogManager.Error(ex.ToString());
			}
		}
	}
}
namespace GTFuckingXP.Scripts
{
	public class BlinkKnife : MonoBehaviour
	{
		public void Update()
		{
		}
	}
	public class DevModeTools : MonoBehaviour
	{
		private static bool _guiInitialized;

		private static GUIStyle _normalStyle;

		private readonly float _xPos = 30f;

		private readonly float _yPos = (float)(Screen.height / 2) - 300f;

		private bool _active = true;

		private string _addXpNumber;

		private float _timeTillXpNumberInvalid;

		public DevModeTools(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public void Update()
		{
			if (Input.GetKeyDown((KeyCode)127))
			{
				_active = !_active;
			}
			if (!_active)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)270) && XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber + 1, out var cheatedXp))
			{
				CheatedXpMessage(cheatedXp);
			}
			if (Input.GetKeyDown((KeyCode)269) && XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber - 1, out var cheatedXp2))
			{
				CheatedXpMessage(cheatedXp2);
			}
			if (Input.GetKeyDown((KeyCode)268))
			{
				XpApi.ReloadData();
			}
			if (Input.GetKeyDown((KeyCode)267))
			{
				List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP");
				LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
				int num = instance.IndexOf(currentLevelLayout);
				if (instance.Count <= num + 1)
				{
					XpApi.ChangeCurrentLevelLayout(instance[0]);
				}
				else
				{
					XpApi.ChangeCurrentLevelLayout(instance[num + 1]);
				}
			}
			if (Input.GetKeyDown((KeyCode)256))
			{
				AddCharToXpNumber("0");
			}
			if (Input.GetKeyDown((KeyCode)257))
			{
				AddCharToXpNumber("1");
			}
			if (Input.GetKeyDown((KeyCode)258))
			{
				AddCharToXpNumber("2");
			}
			if (Input.GetKeyDown((KeyCode)259))
			{
				AddCharToXpNumber("3");
			}
			if (Input.GetKeyDown((KeyCode)260))
			{
				AddCharToXpNumber("4");
			}
			if (Input.GetKeyDown((KeyCode)261))
			{
				AddCharToXpNumber("5");
			}
			if (Input.GetKeyDown((KeyCode)262))
			{
				AddCharToXpNumber("6");
			}
			if (Input.GetKeyDown((KeyCode)263))
			{
				AddCharToXpNumber("7");
			}
			if (Input.GetKeyDown((KeyCode)264))
			{
				AddCharToXpNumber("8");
			}
			if (Input.GetKeyDown((KeyCode)265))
			{
				AddCharToXpNumber("9");
			}
			if (Input.GetKeyDown((KeyCode)271) && !string.IsNullOrEmpty(_addXpNumber))
			{
				XpApi.AddXp(Convert.ToUInt32(_addXpNumber));
				PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), "Cheated " + _addXpNumber + "XP", (PlayerAgent)null);
			}
		}

		public void OnGUI()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if (_active)
			{
				if (!_guiInitialized)
				{
					_normalStyle = new GUIStyle(GUI.skin.GetStyle("label"))
					{
						fontSize = 22
					};
					_guiInitialized = true;
				}
				GUI.contentColor = Color.white;
				GUI.Label(new Rect(_xPos, _yPos, 400f, 30f), "Xp dev tools:", _normalStyle);
				GUI.Label(new Rect(_xPos, _yPos + 25f, 400f, 30f), "Reload xp data : Keypad*", _normalStyle);
				GUI.Label(new Rect(_xPos, _yPos + 50f, 400f, 30f), "Change class : Keypad/", _normalStyle);
				GUI.Label(new Rect(_xPos, _yPos + 75f, 400f, 30f), "Level up : Keypad+", _normalStyle);
				GUI.Label(new Rect(_xPos, _yPos + 100f, 400f, 30f), "Level down : Keypad-", _normalStyle);
				GUI.Label(new Rect(_xPos, _yPos + 125f, 400f, 30f), "AddXP \"" + _addXpNumber + "\" KeypadEnter to add XP", _normalStyle);
			}
		}

		private void AddCharToXpNumber(string number)
		{
			if (Time.time > _timeTillXpNumberInvalid)
			{
				_addXpNumber = string.Empty;
			}
			_addXpNumber += number;
			_timeTillXpNumberInvalid = Time.time + 2f;
		}

		private void CheatedXpMessage(float xpAmount)
		{
			PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), $"Cheated {xpAmount}XP", (PlayerAgent)null);
		}
	}
	internal class DevTools : BaseMenu
	{
		public DevTools(IntPtr intPtr)
			: base(intPtr)
		{
			//IL_0017: 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_0045: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			((BaseMenu)this).PageTitle = "Xp dev tools";
			base._currentState = (MenuStates)2;
			base._tools.Add(new Tool("Reload xp data", MenuInputProvider.F1, false, (Action<Tool>)ReloadData, (Action<Tool, bool>)null, false));
			base._tools.Add(new Tool("Change class", MenuInputProvider.F2, false, (Action<Tool>)ChangeClass, (Action<Tool, bool>)null, false));
			base._tools.Add(new Tool("Level up", MenuInputProvider.F3, false, (Action<Tool>)LevelUp, (Action<Tool, bool>)null, false));
			base._tools.Add(new Tool("Level down", MenuInputProvider.F4, false, (Action<Tool>)LevelDown, (Action<Tool, bool>)null, false));
		}

		protected override void Update()
		{
			((BaseMenu)this).Update();
		}

		public void ReloadData(Tool _)
		{
			XpApi.ReloadData();
		}

		public void LevelUp(Tool _)
		{
			if (XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber + 1, out var cheatedXp))
			{
				CheatedXpMessage(cheatedXp);
			}
		}

		public void LevelDown(Tool _)
		{
			if (XpApi.SetCurrentLevel(CacheApiWrapper.GetActiveLevel().LevelNumber - 1, out var cheatedXp))
			{
				CheatedXpMessage(cheatedXp);
			}
		}

		public void ChangeClass(Tool _)
		{
			List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP");
			LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
			int num = instance.IndexOf(currentLevelLayout);
			if (instance.Count <= num + 1)
			{
				XpApi.ChangeCurrentLevelLayout(instance[0]);
			}
			else
			{
				XpApi.ChangeCurrentLevelLayout(instance[num + 1]);
			}
		}

		private void CheatedXpMessage(float xpAmount)
		{
			PlayerChatManager.WantToSentTextMessage(PlayerManager.GetLocalPlayerAgent(), $"Cheated {xpAmount}XP", (PlayerAgent)null);
		}
	}
	internal class XpBar : MonoBehaviour
	{
		private RectTransform _xpBar;

		private SpriteRenderer _xpProgressBar;

		private TextMeshPro _textUi;

		public XpBar(IntPtr intPtr)
			: base(intPtr)
		{
			XpBarStuff();
		}

		public void UpdateUiString(Level currentLevel, Level nextLevel, uint currentTotalXp, string header)
		{
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			string text;
			if (string.IsNullOrEmpty(currentLevel.CustomLevelStatsText))
			{
				if (nextLevel != null)
				{
					uint num = currentTotalXp - currentLevel.TotalXpRequired;
					uint value = nextLevel.TotalXpRequired - currentLevel.TotalXpRequired;
					StringBuilder stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder3 = stringBuilder2;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2);
					handler.AppendLiteral("Classname: ");
					handler.AppendFormatted(header);
					stringBuilder3.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder4 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(10, 2, stringBuilder2);
					handler.AppendLiteral("MaxHP ");
					handler.AppendFormatted(currentLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp());
					handler.AppendLiteral(" => ");
					handler.AppendFormatted(nextLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp());
					stringBuilder4.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder5 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(7, 2, stringBuilder2);
					handler.AppendLiteral("MD ");
					handler.AppendFormatted(currentLevel.MeleeDamageMultiplier);
					handler.AppendLiteral(" => ");
					handler.AppendFormatted(nextLevel.MeleeDamageMultiplier);
					stringBuilder5.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder6 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(7, 2, stringBuilder2);
					handler.AppendLiteral("WD ");
					handler.AppendFormatted(currentLevel.WeaponDamageMultiplier);
					handler.AppendLiteral(" => ");
					handler.AppendFormatted(nextLevel.WeaponDamageMultiplier);
					stringBuilder6.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder7 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(13, 3, stringBuilder2);
					handler.AppendLiteral("Level ");
					handler.AppendFormatted(currentLevel.LevelNumber);
					handler.AppendLiteral(" => ");
					handler.AppendFormatted(num);
					handler.AppendLiteral(" / ");
					handler.AppendFormatted(value);
					stringBuilder7.AppendLine(ref handler);
					((Component)_xpProgressBar).gameObject.SetActive(false);
					double num2 = (double)num / Convert.ToDouble(value);
					_xpProgressBar.size = new Vector2((float)(num2 * 300.0), 20f);
				}
				else
				{
					StringBuilder stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder8 = stringBuilder2;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder2);
					handler.AppendLiteral("Classname: ");
					handler.AppendFormatted(header);
					stringBuilder8.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder9 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2);
					handler.AppendLiteral("MaxHP ");
					handler.AppendFormatted(currentLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp());
					stringBuilder9.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder10 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2);
					handler.AppendLiteral("MD ");
					handler.AppendFormatted(currentLevel.MeleeDamageMultiplier);
					stringBuilder10.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder11 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2);
					handler.AppendLiteral("WD ");
					handler.AppendFormatted(currentLevel.WeaponDamageMultiplier);
					stringBuilder11.AppendLine(ref handler);
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder12 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2);
					handler.AppendLiteral("Level ");
					handler.AppendFormatted(currentLevel.LevelNumber);
					stringBuilder12.AppendLine(ref handler);
					((Component)_xpProgressBar).gameObject.SetActive(false);
				}
				text = stringBuilder.ToString();
			}
			else
			{
				stringBuilder.Append(currentLevel.CustomLevelStatsText);
				text = stringBuilder.ToString();
				if (nextLevel == null)
				{
					((Component)_xpProgressBar).gameObject.SetActive(false);
					text = string.Format(text, $"Level {currentLevel.LevelNumber}");
				}
				else
				{
					uint num3 = currentTotalXp - currentLevel.TotalXpRequired;
					uint value2 = nextLevel.TotalXpRequired - currentLevel.TotalXpRequired;
					double num4 = (double)num3 / Convert.ToDouble(value2);
					_xpProgressBar.size = new Vector2((float)(num4 * 300.0), 20f);
					text = string.Format(text, $"Level {currentLevel.LevelNumber} => {num3} / {value2}");
				}
			}
			((TMP_Text)_textUi).text = text;
			((TMP_Text)_textUi).ForceMeshUpdate(false, false);
		}

		public void HideTextUi()
		{
			((TMP_Text)_textUi).text = "";
			((TMP_Text)_textUi).ForceMeshUpdate(false, false);
		}

		public void XpBarStuff()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if (!CacheApi.TryGetInstance<RectTransform>(ref _xpBar, "GTF_XP", false) || !CacheApi.TryGetInstance<SpriteRenderer>(ref _xpProgressBar, "GTF_XP", false) || !CacheApi.TryGetInstance<TextMeshPro>(ref _textUi, "GTF_XP", false))
			{
				PUI_LocalPlayerStatus playerStatus = GuiManager.Current.m_playerLayer.m_playerStatus;
				_xpBar = ((Component)((Component)playerStatus.m_health2).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("XpBarRenderer");
				((Component)_xpBar).transform.Translate(0f, (float)Screen.height * 50f / 2560f, 0f);
				((Transform)_xpBar).Rotate(0f, 180f, 0f);
				((Renderer)((Component)((Transform)_xpBar).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false;
				_xpProgressBar = ((Component)((Transform)_xpBar).GetChild(1)).GetComponent<SpriteRenderer>();
				_xpProgressBar.size = new Vector2(3f, 10f);
				_xpProgressBar.color = new Color(1f, 64f / 85f, 0.79607844f);
				_textUi = ((Component)GuiManager.Current.m_watermarkLayer.m_watermark.m_watermarkText).gameObject.Instantiate<TextMeshPro>("XpText");
				_textUi.transform.Translate(new Vector3(-120f, 0f, 0f));
				CacheApi.SaveInstance<TextMeshPro>(_textUi, "GTF_XP");
				CacheApi.SaveInstance<RectTransform>(_xpBar, "GTF_XP");
				CacheApi.SaveInstance<SpriteRenderer>(_xpProgressBar, "GTF_XP");
				((Component)_xpBar).gameObject.SetActive(false);
			}
		}
	}
	internal class XpHandler : MonoBehaviour
	{
		private bool _hasDebuff;

		private float _nextUpdate;

		public uint CurrentTotalXp { get; internal set; }

		public Level NextLevel { get; internal set; }

		public bool IsMaxLevel => NextLevel == null;

		public XpHandler(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public void Awake()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (CacheApiWrapper.TryGetXpStorageData(out (LevelLayout, uint) checkpointData))
			{
				LogManager.Message("Found old xp storage data!");
				CacheApiWrapper.SetCurrentLevelLayout(checkpointData.Item1);
				Level level0 = checkpointData.Item1.Levels.First((Level it) => it.LevelNumber == 0);
				NextLevel = checkpointData.Item1.Levels.FirstOrDefault((Level it) => it.LevelNumber == level0.LevelNumber + 1);
				CacheApiWrapper.SetActiveLevel(level0, sendToOtherPeople: false);
				CurrentTotalXp = 0u;
				AddXp(new DummyXp(checkpointData.Item2, checkpointData.Item2), default(Vector3));
			}
			else
			{
				LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
				Level newActiveLevel = currentLevelLayout.Levels.First((Level it) => it.LevelNumber == 0);
				NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == newActiveLevel.LevelNumber + 1);
				CurrentTotalXp = 0u;
				ChangeCurrentLevel(newActiveLevel, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, newActiveLevel.LevelNumber));
				CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), NextLevel, CurrentTotalXp, currentLevelLayout.Header);
			}
			_nextUpdate = Time.time + 300f;
		}

		public void Update()
		{
			if (_nextUpdate < Time.time)
			{
				_nextUpdate = Time.time + 300f;
			}
		}

		public void AddXp(IXpData xpData, Vector3 xpTextPosition, bool forceDebuffXp = false, string xpPopupColor = "<#F80>")
		{
			//IL_00a1: 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)
			uint num = ((forceDebuffXp || _hasDebuff) ? xpData.DebuffXp : xpData.XpGain);
			int num2 = xpData.LevelScalingXpDecrese * CacheApiWrapper.GetActiveLevel().LevelNumber;
			num = (uint)((num <= num2) ? 1u : (num - num2));
			CurrentTotalXp += num;
			LogManager.Debug($"Giving xp Amount {num}, new total Xp is {CurrentTotalXp}");
			if (!CheckForLevelThresholdReached(xpTextPosition, out string currentClassName) && BepInExLoader.XpPopups.Value && NextLevel != null)
			{
				DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, $"{xpPopupColor}{num}XP"));
			}
			CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), NextLevel, CurrentTotalXp, currentClassName);
		}

		public bool CheckForLevelThresholdReached(Vector3 xpTextPosition, out string currentClassName)
		{
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
			currentClassName = currentLevelLayout.Header;
			if (IsMaxLevel)
			{
				return false;
			}
			Level activeLevel = CacheApiWrapper.GetActiveLevel();
			IEnumerable<Level> source = currentLevelLayout.Levels.Where((Level it) => it.LevelNumber > CacheApiWrapper.GetActiveLevel().LevelNumber && it.TotalXpRequired <= CurrentTotalXp);
			if (source.Count() > 0)
			{
				Level newLevel = source.OrderByDescending((Level it) => it.LevelNumber).First();
				ChangeCurrentLevel(newLevel, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, newLevel.LevelNumber));
				NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == newLevel.LevelNumber + 1);
				if (BepInExLoader.LvlUpPopups.Value)
				{
					if (string.IsNullOrEmpty(newLevel.CustomLevelUpPopupText))
					{
						DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, $"<#f00>LV {newLevel.LevelNumber}\nHP: +<#f80>{Math.Round(newLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp() - activeLevel.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp(), 1)}\n<#f00>MD: <#f80>{Math.Round(newLevel.MeleeDamageMultiplier - activeLevel.MeleeDamageMultiplier, 2)}x \n<#f00>WD: <#f80>{Math.Round(newLevel.WeaponDamageMultiplier - activeLevel.WeaponDamageMultiplier, 2)}x", 4f));
					}
					else
					{
						DamageNumberFactory.CreateFloatingText<FloatingTextBase>((IFloatingTextInfo)(object)new FloatingXpTextInfo(xpTextPosition, newLevel.CustomLevelUpPopupText, 4f));
					}
				}
				return true;
			}
			return false;
		}

		internal void ChangeCurrentLevel(Level newLevel, BoosterBuffs newBoosterBuff = null)
		{
			CacheApiWrapper.SetActiveLevel(newLevel);
			CacheApiWrapper.SetCurrentBoosterBuff(newBoosterBuff);
			LogManager.Debug("saved information.");
			BoosterBuffManager.Instance.ApplyBoosterEffects(PlayerManager.GetLocalPlayerAgent(), newBoosterBuff);
			NetworkApiXpManager.SendBoosterStatsReached(newBoosterBuff);
			Dam_PlayerDamageBase damage = PlayerManager.GetLocalPlayerAgent().Damage;
			float healthMax = ((Dam_SyncedDamageBase)damage).HealthMax;
			float num2 = (((Dam_SyncedDamageBase)damage).HealthMax = CacheApiWrapper.GetDefaultMaxHp() * newLevel.HealthMultiplier);
			((Dam_SyncedDamageBase)damage).Health = ((Dam_SyncedDamageBase)damage).Health + (num2 - healthMax);
			((Il2CppObjectBase)damage).Cast<Dam_PlayerDamageLocal>().UpdateHealthGui();
			ApplySingleUseBuffs(newLevel);
			LogManager.Debug("Pre applying custom scaling effects.");
			CustomScalingBuffManager.ApplyCustomScalingEffects(PlayerManager.GetLocalPlayerAgent(), newLevel.CustomScaling);
		}

		private void ApplySingleUseBuffs(Level reachedLevel)
		{
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			foreach (SingleUseBuff levelUpBonu in reachedLevel.LevelUpBonus)
			{
				switch (levelUpBonu.SingleBuff)
				{
				case SingleBuff.Heal:
					localPlayerAgent.GiveHealth(localPlayerAgent, levelUpBonu.Value);
					break;
				case SingleBuff.Desinfect:
					localPlayerAgent.GiveDisinfection(localPlayerAgent, levelUpBonu.Value);
					break;
				case SingleBuff.AmmunitionMain:
					localPlayerAgent.GiveAmmoRel(localPlayerAgent, levelUpBonu.Value, 0f, 0f);
					break;
				case SingleBuff.AmmunitionSpecial:
					localPlayerAgent.GiveAmmoRel(localPlayerAgent, 0f, levelUpBonu.Value, 0f);
					break;
				case SingleBuff.AmmunitionTool:
					localPlayerAgent.GiveAmmoRel(localPlayerAgent, 0f, 0f, levelUpBonu.Value);
					break;
				}
			}
		}
	}
}
namespace GTFuckingXP.Patches
{
	[HarmonyPatch(typeof(GS_InLevel))]
	public class GS_InLevelPatches
	{
		[HarmonyPatch("Enter")]
		[HarmonyPostfix]
		public static void EnterLevelPostfix()
		{
			LogManager.Debug("Level Enter");
			ScriptManager.Instance.StartLevelScripts();
			UI_Apply.SetSkewing(0f);
		}
	}
	[HarmonyPatch(typeof(GS_AfterLevel))]
	public class GS_AfterLevelPatches
	{
		[HarmonyPatch("CleanupAfterExpedition")]
		[HarmonyPrefix]
		public static void EnterLevelPostfix()
		{
			ScriptManager.Instance.EndLevelScripts();
		}
	}
	[HarmonyPatch(typeof(PlaceNavMarkerOnGO))]
	public class PlaceNavMarkerOnGoPatches
	{
		[HarmonyPatch("UpdateName")]
		[HarmonyPrefix]
		public static void UpdateNamePrefix(PlaceNavMarkerOnGO __instance, ref string name)
		{
			Dictionary<int, Level> playerToLevelMapping = CacheApiWrapper.GetPlayerToLevelMapping();
			if (playerToLevelMapping.TryGetValue(__instance.m_player.PlayerSlotIndex, out var value))
			{
				name = $"<color=#F80>Lv.{value.LevelNumber}</color> {name}";
			}
		}
	}
	[HarmonyPatch(typeof(SNet_SessionHub))]
	public class SnetSessionHubPatches
	{
		[HarmonyPatch("AddPlayerToSession")]
		[HarmonyPostfix]
		public static void AddPlayerToSessionPostfix(SNet_SessionHub __instance)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			if (!CacheApiWrapper.TryGetCurrentLevelLayout(out LevelLayout classLayout))
			{
				return;
			}
			List<Group> instance = CacheApi.GetInstance<List<Group>>("GTF_XP");
			Group group = instance.FirstOrDefault((Group it) => it.PersistentId == classLayout.GroupPersistentId);
			if (group.VisibleForPlayerCount.Contains(__instance.PlayersInSession.Count))
			{
				return;
			}
			if ((int)GameStateManager.Current.m_currentStateName == 5)
			{
				foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase<CM_PlayerLobbyBar>)(object)CM_PageLoadout.Current.m_playerLobbyBars)
				{
					if (item.m_player.Lookup == SNet.LocalPlayer.Lookup)
					{
						CacheApiWrapper.SetCurrentLevelLayout(CacheApi.GetInstance<List<LevelLayout>>("GTF_XP")[0]);
						PlayerLobbyBarPatches.ShowClassesSelector(item);
						break;
					}
				}
				return;
			}
			XpApi.ChangeCurrentLevelLayout(CacheApi.GetInstance<List<LevelLayout>>("GTF_XP")[0]);
		}
	}
}
namespace GTFuckingXP.Patches.SelectLevelPatches
{
	[HarmonyPatch(typeof(CM_PlayerLobbyBar))]
	public class PlayerLobbyBarPatches
	{
		[HarmonyPatch("SetupFromPage")]
		[HarmonyPostfix]
		public static void SetupFromPagePostfix(CM_PlayerLobbyBar __instance)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			CM_PlayerLobbyBar __instance2 = __instance;
			LogManager.Debug($"SetupFromPage Postfix on {((Object)__instance2).GetInstanceID()}");
			CM_LobbyScrollItem classButton = ((Component)__instance2.m_clothesButton).gameObject.Instantiate<CM_LobbyScrollItem>("ClassSelectorButton");
			CacheApi.SaveInformation((object)((Object)__instance2).GetInstanceID(), (object)classButton, "GTF_XP");
			((Component)classButton).transform.Translate(new Vector3(0f, -70f, 0f));
			((CM_Item)classButton).SetOnBtnPressCallback(Action<int>.op_Implicit((Action<int>)delegate(int test)
			{
				LogManager.Debug($"Button pressed with {test} as parameter");
				__instance2.Select();
				classButton.IsSelected = true;
				ShowClassesSelector(__instance2);
			}));
		}

		[HarmonyPatch("HideLoadoutUI")]
		[HarmonyPostfix]
		public static void HideLoadoutUiPostfix(CM_PlayerLobbyBar __instance, bool hide)
		{
			if (!__instance.m_introDone || __instance.m_player == null)
			{
				return;
			}
			CM_LobbyScrollItem information = CacheApi.GetInformation<CM_LobbyScrollItem>((object)((Object)__instance).GetInstanceID(), "GTF_XP");
			if (__instance.m_player.IsLocal)
			{
				((Component)information).gameObject.SetActive(!hide);
				foreach (TextMeshPro item in (Il2CppArrayBase<TextMeshPro>)(object)((CM_Item)information).GetTexts())
				{
					((TMP_Text)item).text = "Class selector";
					((TMP_Text)item).ForceMeshUpdate(false, false);
				}
			}
			if (__instance.m_player.IsBot)
			{
			}
		}

		internal static void ShowClassesSelector(CM_PlayerLobbyBar lobbyBar)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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)
			LogManager.Debug("Calling ShowClass Selector method.");
			lobbyBar.HidePopup();
			lobbyBar.m_popupVisible = true;
			lobbyBar.m_popupScrollWindow.m_infoBoxWidth = 700f;
			((RectTransformComp)lobbyBar.m_popupScrollWindow).SetSize(new Vector2(1600f, 700f));
			lobbyBar.m_popupScrollWindow.ResetHeaders();
			List<Group> instance = CacheApi.GetInstance<List<Group>>("GTF_XP");
			AddHeaders(lobbyBar, instance);
			((RectTransformComp)lobbyBar.m_popupScrollWindow).SetPosition(new Vector2(0f, 350f));
			lobbyBar.m_popupScrollWindow.RespawnInfoBoxFromPrefab(lobbyBar.m_popupInfoBoxWeaponPrefab);
			ChangeClassHeader(instance[0].Name, 0, lobbyBar);
			lobbyBar.ShowPopup();
			CM_ScrollWindowInfoBox infoBox = lobbyBar.m_popupScrollWindow.InfoBox;
			if (!CacheApiWrapper.TryGetAnchorDifference(out var anchorDifference))
			{
				anchorDifference = ((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition.y * -1f - 40f;
				CacheApiWrapper.SetAnchorDifference(anchorDifference);
			}
			((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition = new Vector2(0f, ((TMP_Text)infoBox.m_infoMainTitleText).rectTransform.anchoredPosition.y + anchorDifference);
			((TMP_Text)infoBox.m_infoDescriptionText).rectTransform.anchoredPosition = new Vector2(0f, ((TMP_Text)infoBox.m_infoDescriptionText).rectTransform.anchoredPosition.y + anchorDifference);
			((TMP_Text)infoBox.m_infoDescriptionText).fontSizeMin = ((TMP_Text)infoBox.m_infoDescriptionText).fontSizeMax;
		}

		private static void ChangeClassHeader(string groupName, int key, CM_PlayerLobbyBar lobbyBar)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			LogManager.Debug("Showing groupname " + groupName);
			List<iScrollWindowContent> val = new List<iScrollWindowContent>();
			List<LevelLayout> instance = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP");
			LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
			CM_ScrollWindowInfoBox infoBox = lobbyBar.m_popupScrollWindow.InfoBox;
			float y = infoBox.m_infoMainIcon.size.y;
			((Component)infoBox.m_infoMainIcon).gameObject.SetActive(false);
			((Renderer)infoBox.m_infoMainIcon).enabled = false;
			CM_LobbyScrollItem selected = null;
			foreach (LevelLayout layout in instance)
			{
				if (layout.GroupPersistentId != key)
				{
					continue;
				}
				CM_LobbyScrollItem content = GOUtil.SpawnChildAndGetComp<CM_LobbyScrollItem>(lobbyBar.m_clothesCardPrefab, ((Component)lobbyBar).transform);
				((CM_Item)content).TextMeshRoot = ((Component)lobbyBar.m_parentPage).transform;
				content.SetupFromLobby(((Component)lobbyBar).transform, lobbyBar, true);
				((RectTransformComp)content).ForcePopupLayer(true, (GameObject)null);
				((TMP_Text)content.m_descText).text = "";
				((TMP_Text)content.m_subTitleText).text = "";
				if (layout.PersistentId == currentLevelLayout.PersistentId)
				{
					selected = content;
					selected.IsSelected = true;
					SelectItem(content, selected);
				}
				((TMP_Text)content.m_nameText).text = layout.Header;
				((CM_Item)content).OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)delegate
				{
					//IL_0127: Unknown result type (might be due to invalid IL or missing references)
					//IL_0131: Expected O, but got Unknown
					LogManager.Debug($"LayoutName {layout.Header} and Id is {layout.PersistentId}");
					if ((Object)(object)selected != (Object)null)
					{
						selected.IsSelected = false;
					}
					content.IsSelected = true;
					SelectItem(content, selected);
					selected = content;
					CoroutineManager.BlinkIn(((Component)content).gameObject, 0f);
					infoBox.SetInfoBox(layout.Header, "", layout.InfoText, "", "", new Sprite());
					CacheApiWrapper.SetCurrentLevelLayout(layout);
				});
				((CM_Item)content).m_alphaSpriteOnHover = true;
				((CM_Item)content).m_alphaTextOnHover = true;
				val.Add(((Il2CppObjectBase)content).Cast<iScrollWindowContent>());
			}
			lobbyBar.m_popupScrollWindow.SetContentItems(val, 0f);
			Enumerator<iScrollWindowContent> enumerator2 = val.GetEnumerator();
			while (enumerator2.MoveNext())
			{
				iScrollWindowContent current = enumerator2.Current;
				((Il2CppObjectBase)current).Cast<CM_LobbyScrollItem>().UpdateSizesAndOffsets();
			}
			lobbyBar.ShowPopup();
			lobbyBar.m_popupScrollWindow.SelectHeader(key);
			Transform val2 = ((Component)infoBox).transform.FindChild("InfoBox/IconBackground");
			LogManager.Debug($"Child is null {val2 == null}");
			((Component)val2).gameObject.SetActive(false);
		}

		private static void SelectItem(CM_LobbyScrollItem newSelectItem, CM_LobbyScrollItem oldSelectItem)
		{
			if ((Object)(object)oldSelectItem != (Object)null)
			{
				((TMP_Text)oldSelectItem.m_subTitleText).text = "";
				CacheApi.SaveInstance<CM_LobbyScrollItem>((CM_LobbyScrollItem)null, "GTF_XP");
			}
			if ((Object)(object)newSelectItem != (Object)null)
			{
				((TMP_Text)newSelectItem.m_subTitleText).text = "<color=orange>" + Text.Get(492u) + "</color>";
				CacheApi.SaveInstance<CM_LobbyScrollItem>(newSelectItem, "GTF_XP");
			}
		}

		private static void AddHeaders(CM_PlayerLobbyBar lobbyBar, List<Group> groups)
		{
			CM_PlayerLobbyBar lobbyBar2 = lobbyBar;
			int num = 0;
			int count = SNet.SessionHub.PlayersInSession.Count;
			bool flag = false;
			foreach (Group group in groups)
			{
				if (num <= 5 && group.VisibleForPlayerCount != null && group.VisibleForPlayerCount.Contains(count))
				{
					lobbyBar2.m_popupScrollWindow.AddHeader(group.Name, group.PersistentId, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex)
					{
						LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or {group.PersistentId}");
						ChangeClassHeader(group.Name, group.PersistentId, lobbyBar2);
					}));
					flag = true;
					num++;
				}
			}
			if (flag)
			{
				return;
			}
			Group group2 = groups.FirstOrDefault((Group it) => it.PersistentId == 0);
			Group group3 = groups.FirstOrDefault((Group it) => it.PersistentId == 1);
			Group group4 = groups.FirstOrDefault((Group it) => it.PersistentId == 2);
			Group group5 = groups.FirstOrDefault((Group it) => it.PersistentId == 3);
			if (group2 != null)
			{
				lobbyBar2.m_popupScrollWindow.AddHeader(group2.Name, 0, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex)
				{
					LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 0");
					ChangeClassHeader(group2.Name, 0, lobbyBar2);
				}));
			}
			if (group3 != null)
			{
				lobbyBar2.m_popupScrollWindow.AddHeader(group3.Name, 1, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex)
				{
					LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 1");
					ChangeClassHeader(group3.Name, 1, lobbyBar2);
				}));
			}
			if (group4 != null)
			{
				lobbyBar2.m_popupScrollWindow.AddHeader(group4.Name, 2, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex)
				{
					LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 2");
					ChangeClassHeader(group4.Name, 2, lobbyBar2);
				}));
			}
			if (group5 != null)
			{
				lobbyBar2.m_popupScrollWindow.AddHeader(group5.Name, 3, Action<int>.op_Implicit((Action<int>)delegate(int headerIndex)
				{
					LogManager.Debug($"Header select call. HeaderIndex was {headerIndex}, or 3");
					ChangeClassHeader(group5.Name, 3, lobbyBar2);
				}));
			}
		}
	}
}
namespace GTFuckingXP.Information
{
	public static class DefaultXpData
	{
		public static List<EnemyXp> GetDefaultEnemyXp()
		{
			List<EnemyXp> list = new List<EnemyXp>();
			Il2CppArrayBase<EnemyBalancingDataBlock> allBlocks = GameDataBlockBase<EnemyBalancingDataBlock>.GetAllBlocks();
			foreach (EnemyDataBlock enemy in GameDataBlockBase<EnemyDataBlock>.GetAllBlocks())
			{
				EnemyBalancingDataBlock val = ((IEnumerable<EnemyBalancingDataBlock>)allBlocks).FirstOrDefault((Func<EnemyBalancingDataBlock, bool>)((EnemyBalancingDataBlock it) => ((GameDataBlockBase<EnemyBalancingDataBlock>)(object)it).persistentID == enemy.BalancingDataId));
				float num;
				if (val == null)
				{
					LogManager.Warn($"No balance datablock found for balance id {enemy.BalancingDataId} ({((GameDataBlockBase<EnemyDataBlock>)(object)enemy).name})!");
					num = 20f;
				}
				else
				{
					num = val.Health.HealthMax;
				}
				int num2 = (int)(num / 35f);
				num2 = ((num2 <= 0) ? 1 : num2);
				list.Add(new EnemyXp(((GameDataBlockBase<EnemyDataBlock>)(object)enemy).persistentID, ((GameDataBlockBase<EnemyDataBlock>)(object)enemy).name, (uint)(num / 2f), (uint)(num / 4f), num2));
			}
			return list;
		}

		public static List<LevelLayout> GetDefaultLevelLayout()
		{
			List<LevelLayout> list = new List<LevelLayout>();
			List<GTFuckingXP.Information.Level.Level> list2 = new List<GTFuckingXP.Information.Level.Level>();
			for (int i = 0; i <= 60; i++)
			{
				float num = 1f + 0.25f * (float)i;
				uint totalXp = Convert.ToUInt32(250.0 * (0.8 + 0.2 * (double)i) * (double)i);
				List<SingleUseBuff> list3 = new List<SingleUseBuff>();
				if (i % 5 == 0 && i != 0)
				{
					list3.Add(new SingleUseBuff(SingleBuff.Heal, 1f));
					list3.Add(new SingleUseBuff(SingleBuff.Desinfect, 1f));
					list3.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 1f));
					list3.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 1f));
					list3.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 1f));
				}
				list2.Add(new GTFuckingXP.Information.Level.Level(i, totalXp, num, num, num, list3, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(1, "All Rounder", 0, "Scales equally acceptable with everything.", list2));
			List<GTFuckingXP.Information.Level.Level> list4 = new List<GTFuckingXP.Information.Level.Level>();
			for (int j = 0; j <= 12; j++)
			{
				float num2 = 1f + 0.5f * (float)j;
				uint totalXp2 = Convert.ToUInt32(150.0 * (0.8 + 0.2 * (double)j) * (double)j);
				List<SingleUseBuff> list5 = new List<SingleUseBuff>();
				list5.Add(new SingleUseBuff(SingleBuff.Heal, 0.1f));
				list5.Add(new SingleUseBuff(SingleBuff.Desinfect, 0.1f));
				list4.Add(new GTFuckingXP.Information.Level.Level(j, totalXp2, 0.1f * num2, 1.5f * num2, 1.4f * num2, list5, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(2, "Glass cannon", 0, "Great scaling, but only 12 levels with no HP.", list4));
			List<GTFuckingXP.Information.Level.Level> list6 = new List<GTFuckingXP.Information.Level.Level>();
			for (int k = 0; k <= 80; k++)
			{
				float num3 = 1f + 0.1f * (float)k;
				uint totalXp3 = Convert.ToUInt32(100.0 * (0.8 + 0.2 * (double)k) * (double)k);
				List<SingleUseBuff> list7 = new List<SingleUseBuff>();
				if (k % 2 == 0 && k != 0)
				{
					list7.Add(new SingleUseBuff(SingleBuff.Heal, 0.5f));
					list7.Add(new SingleUseBuff(SingleBuff.Desinfect, 0.2f));
				}
				list6.Add(new GTFuckingXP.Information.Level.Level(k, totalXp3, 5f * num3, 0.5f * num3, 0.5f * num3, list7, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(3, "Tank", 0, "Slow overall scaling, very good HP but decreased damage output.", list6));
			List<GTFuckingXP.Information.Level.Level> list8 = new List<GTFuckingXP.Information.Level.Level>();
			for (int l = 0; l <= 20; l++)
			{
				float num4 = 1f + 0.5f * (float)l;
				uint totalXp4 = Convert.ToUInt32(400.0 * (0.8 + 0.2 * (double)l) * (double)l);
				List<SingleUseBuff> list9 = new List<SingleUseBuff>();
				list9.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 1f));
				list9.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 1f));
				list9.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 1f));
				list8.Add(new GTFuckingXP.Information.Level.Level(l, totalXp4, 0.05f * num4, 30f * num4, 0.1f * num4, list9, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(4, "Kamikaze", 0, "No HP, no weapondamage, melee for life\nBut has a curse of getting regulary useless ammunition.", list8));
			List<GTFuckingXP.Information.Level.Level> list10 = new List<GTFuckingXP.Information.Level.Level>();
			for (int m = 0; m <= 20; m++)
			{
				float num5 = 1f + 0.25f * (float)m;
				uint totalXp5 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)m) * (double)m);
				List<SingleUseBuff> list11 = new List<SingleUseBuff>();
				list11.Add(new SingleUseBuff(SingleBuff.Heal, 0.2f));
				list10.Add(new GTFuckingXP.Information.Level.Level(m, totalXp5, 1f * num5, 1f * num5 + 1f, num5 * 0.5f - 0.5f, list11, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(5, "Melee Main", 0, "Acceptable scaling, faster leveling\nCapable of tanking some hits and deals great melee damage. May lack a bit of Weapondamage", list10));
			List<GTFuckingXP.Information.Level.Level> list12 = new List<GTFuckingXP.Information.Level.Level>();
			for (int n = 0; n <= 20; n++)
			{
				float num6 = 1f + 0.5f * (float)n;
				uint totalXp6 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)n) * (double)n);
				List<SingleUseBuff> singleUseBuffs = new List<SingleUseBuff>();
				list12.Add(new GTFuckingXP.Information.Level.Level(n, totalXp6, num6, num6, 0f, singleUseBuffs, new List<CustomScalingBuff>()));
			}
			list.Add(new LevelLayout(6, "Boxer", 1, "Great Scaling.\nNo weapon damage!\nVery tanky against melee damage but can't withstand any shooter.", list12));
			List<GTFuckingXP.Information.Level.Level> list13 = new List<GTFuckingXP.Information.Level.Level>();
			for (int num7 = 0; num7 <= 20; num7++)
			{
				float num8 = 1f + 0.5f * (float)num7;
				uint totalXp7 = Convert.ToUInt32(200.0 * (0.8 + 0.2 * (double)num7) * (double)num7);
				List<SingleUseBuff> list14 = new List<SingleUseBuff>();
				list14.Add(new SingleUseBuff(SingleBuff.AmmunitionMain, 0.2f));
				list14.Add(new SingleUseBuff(SingleBuff.AmmunitionSpecial, 0.2f));
				list14.Add(new SingleUseBuff(SingleBuff.AmmunitionTool, 0.2f));
				List<CustomScalingBuff> list15 = new List<CustomScalingBuff>();
				if (num7 != 0)
				{
					list15.Add(new CustomScalingBuff(CustomScaling.MeleeHitBoxSizeMultiplier, num7 * 5));
					list15.Add(new CustomScalingBuff(CustomScaling.MeleeRangeMultiplier, num7));
					list15.Add(new CustomScalingBuff(CustomScaling.MovementSpeedMultiplier, 1f + (float)num7 * 0.3f));
					list15.Add(new CustomScalingBuff(CustomScaling.AntiFogSphere, num7 * 2));
				}
				list13.Add(new GTFuckingXP.Information.Level.Level(num7, totalXp7, num8, num8, 0f, list14, list15));
			}
			list.Add(new LevelLayout(7, "SpeedRunner", 1, "Gets increasingly faster while playing, so you can circle kite even easier.", list13));
			return list;
		}

		public static List<BoosterBuffs> GetDefaultBoosterBuffs()
		{
			List<BoosterBuffs> list = new List<BoosterBuffs>();
			list.Add(new BoosterBuffs(6, new List<int>
			{
				0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
				10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
				20
			}, new Dictionary<AgentModifier, float>
			{
				{
					(AgentModifier)6,
					1000f
				},
				{
					(AgentModifier)7,
					-500f
				}
			}));
			return list;
		}

		public static List<Group> GetDefaultGroups()
		{
			List<Group> list = new List<Group>();
			list.Add(new Group(0, "Example Classes", new List<int> { 1, 2, 3, 4 }));
			list.Add(new Group(1, "For gods sake, don't use it", new List<int> { 1 }));
			return list;
		}
	}
	internal class DummyXp : IXpData
	{
		public uint XpGain { get; set; }

		public uint DebuffXp { get; set; }

		public int LevelScalingXpDecrese { get; set; }

		public DummyXp(uint xpGain, uint debuffXp)
		{
			XpGain = xpGain;
			DebuffXp = debuffXp;
			LevelScalingXpDecrese = 0;
		}
	}
	public class FloatingXpTextInfo : IFloatingTextInfo
	{
		public Vector3 Velocity { get; }

		public Vector3 SpawnPosition { get; }

		public float Gravity => 0f;

		public float LifeTime { get; }

		public string Text { get; }

		public FloatingXpTextInfo(Vector3 position, string text, float lifeTime = 2f)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Velocity = new Vector3(0f, 0.1f, 0f);
			SpawnPosition = position;
			Text = text;
			LifeTime = lifeTime;
		}

		public void OnUpdate(TextMeshPro tmp, FloatingTextBase textBase)
		{
		}

		public void UpdateTextMesh(TextMeshPro tmp)
		{
		}
	}
	public interface IXpData
	{
		uint XpGain { get; set; }

		uint DebuffXp { get; set; }

		int LevelScalingXpDecrese { get; set; }
	}
	public enum TermsOfUsage
	{
		Undecided,
		Accepted,
		Declined,
		Anonymized
	}
}
namespace GTFuckingXP.Information.WebModels
{
	public class XpWebModel
	{
		public string SteamId { get; set; }

		public string PlayFabId { get; set; }

		public string NickName { get; set; }

		public XpWebModel(TermsOfUsage howToHandleData)
		{
			switch (howToHandleData)
			{
			case TermsOfUsage.Accepted:
				SteamId = SteamManager.LocalPlayerID.ToString();
				PlayFabId = PlayFabManager.EntityID;
				NickName = SteamManager.LocalPlayerName;
				break;
			case TermsOfUsage.Anonymized:
				SteamId = "Unknown";
				PlayFabId = "Unknown";
				NickName = "Unknown";
				break;
			default:
				throw new Exception("You should not create a data package if there is no consent!");
			}
		}
	}
}
namespace GTFuckingXP.Information.NetworkingInfo
{
	public struct BoosterInfo
	{
		public float F1;

		public float F2;

		public float F3;

		public float F4;

		public float F5;

		public float F6;

		public float F7;

		public float F8;

		public float F9;

		public float F10;

		public float F11;

		public float F12;

		public float F13;

		public float F14;

		public float F15;

		public float F16;

		public float F17;

		public float F18;

		public float F19;

		public float F20;

		public float F21;

		public float F22;

		public float F23;

		public float F24;

		public float F25;

		public float F26;

		public float F27;

		public float F28;

		public float F29;

		public float F30;

		public float F31;

		public float F32;

		public float F33;

		public float F34;

		public float F35;

		public float F36;

		public float F37;

		public float F38;

		public float F39;

		public float F40;

		public float F41;

		public float F42;

		public float F43;

		public float F44;

		public float F45;

		public float F46;

		public float F47;

		public float F48;

		public float F49;

		public float F50;

		public float F51;

		public float F52;

		public float F53;

		public float F54;

		public BoosterInfo(float[] boosterValues)
		{
			if (boosterValues.Length > 54)
			{
				LogManager.Error("There are more values in Boosters values, than supported.\nPlease message \"Endskill\" about that issue!");
			}
			else if (boosterValues.Length < 54)
			{
				LogManager.Error("There are less than 47 Booster values!");
			}
			F1 = boosterValues[0];
			F2 = boosterValues[1];
			F3 = boosterValues[2];
			F4 = boosterValues[3];
			F5 = boosterValues[4];
			F6 = boosterValues[5];
			F7 = boosterValues[6];
			F8 = boosterValues[7];
			F9 = boosterValues[8];
			F10 = boosterValues[9];
			F11 = boosterValues[10];
			F12 = boosterValues[11];
			F13 = boosterValues[12];
			F14 = boosterValues[13];
			F15 = boosterValues[14];
			F16 = boosterValues[15];
			F17 = boosterValues[16];
			F18 = boosterValues[17];
			F19 = boosterValues[18];
			F20 = boosterValues[19];
			F21 = boosterValues[20];
			F22 = boosterValues[21];
			F23 = boosterValues[22];
			F24 = boosterValues[23];
			F25 = boosterValues[24];
			F26 = boosterValues[25];
			F27 = boosterValues[26];
			F28 = boosterValues[27];
			F29 = boosterValues[28];
			F30 = boosterValues[29];
			F31 = boosterValues[30];
			F32 = boosterValues[31];
			F33 = boosterValues[32];
			F34 = boosterValues[33];
			F35 = boosterValues[34];
			F36 = boosterValues[35];
			F37 = boosterValues[36];
			F38 = boosterValues[37];
			F39 = boosterValues[38];
			F40 = boosterValues[39];
			F41 = boosterValues[40];
			F42 = boosterValues[41];
			F43 = boosterValues[42];
			F44 = boosterValues[43];
			F45 = boosterValues[44];
			F46 = boosterValues[45];
			F47 = boosterValues[46];
			F48 = boosterValues[47];
			F49 = boosterValues[48];
			F50 = boosterValues[49];
			F51 = boosterValues[50];
			F52 = boosterValues[51];
			F53 = boosterValues[52];
			F54 = boosterValues[53];
		}

		public float[] GetBoosterValues()
		{
			return new float[54]
			{
				F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,
				F11, F12, F13, F14, F15, F16, F17, F18, F19, F20,
				F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
				F31, F32, F33, F34, F35, F36, F37, F38, F39, F40,
				F41, F42, F43, F44, F45, F46, F47, F48, F49, F50,
				F51, F52, F53, F54
			};
		}

		public static implicit operator BoosterInfo(BoosterBuffs buff)
		{
			//IL_0029: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			Array values = Enum.GetValues(typeof(AgentModifier));
			float[] array = new float[values.Length];
			for (int i = 0; i < values.Length; i++)
			{
				AgentModifier key = (AgentModifier)values.GetValue(i);
				if (buff != null && buff.ValueToBoosterEffects.TryGetValue(key, out var value))
				{
					array[i] = value;
				}
				else
				{
					array[i] = 0f;
				}
			}
			return new BoosterInfo(array);
		}
	}
	public struct GtfoApiXpInfo : IXpData
	{
		public bool ForceDebuffXp { get; set; }

		public uint XpGain { get; set; }

		public uint DebuffXp { get; set; }

		public int LevelScalingXpDecrese { get; set; }

		public float PositionX { get; set; }

		public float PositionY { get; set; }

		public float PositionZ { get; set; }

		public GtfoApiXpInfo(uint xpGain, uint debuffXp, int levelScaling, Vector3 position, bool forceDebuffXp = false)
		{
			//IL_0023: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			XpGain = xpGain;
			DebuffXp = debuffXp;
			LevelScalingXpDecrese = levelScaling;
			ForceDebuffXp = forceDebuffXp;
			PositionX = position.x;
			PositionY = position.y;
			PositionZ = position.z;
		}
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
	public struct LevelReachedInfo
	{
		public int LevelNumber;

		public float HealthMultiplier;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 230)]
		public string CustomScaling;

		public LevelReachedInfo(int levelNumber, float healthMultiplier, string customScaling)
		{
			LevelNumber = levelNumber;
			HealthMultiplier = healthMultiplier;
			CustomScaling = customScaling;
		}
	}
	public struct StaticXpInfo : IXpData
	{
		public uint XpGain { get; set; }

		public uint DebuffXp { get; set; }

		public int LevelScalingXpDecrese { get; set; }

		public Vector3 Position { get; set; }

		public StaticXpInfo(uint xpGain, uint debuffXp, int levelScaling, Vector3 position)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			XpGain = xpGain;
			DebuffXp = debuffXp;
			LevelScalingXpDecrese = levelScaling;
			Position = position;
		}
	}
}
namespace GTFuckingXP.Information.Level
{
	public class BoosterBuffs
	{
		public int ClassLayoutPersistentId { get; set; }

		public List<int> ActiveLevels { get; set; }

		public Dictionary<AgentModifier, float> ValueToBoosterEffects { get; set; }

		public BoosterBuffs(int classLayoutPersistentId, List<int> activeLevels, Dictionary<AgentModifier, float> valueToBoosterEffects)
		{
			ClassLayoutPersistentId = classLayoutPersistentId;
			ActiveLevels = activeLevels;
			ValueToBoosterEffects = valueToBoosterEffects;
		}

		public static implicit operator BoosterBuffs(BoosterInfo boosterInfo)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Array values = Enum.GetValues(typeof(AgentModifier));
			Dictionary<AgentModifier, float> dictionary = new Dictionary<AgentModifier, float>();
			float[] boosterValues = boosterInfo.GetBoosterValues();
			for (int i = 0; i < values.Length; i++)
			{
				if (boosterValues[i] != 0f)
				{
					AgentModifier key = (AgentModifier)values.GetValue(i);
					dictionary[key] = boosterValues[i];
				}
			}
			return new BoosterBuffs(0, null, dictionary);
		}
	}
	public class CustomScalingBuff
	{
		public CustomScaling CustomBuff { get; set; }

		public float Value { get; set; }

		public CustomScalingBuff(CustomScaling customBuff, float value)
		{
			CustomBuff = customBuff;
			Value = value;
		}
	}
	public class Level
	{
		public int LevelNumber { get; set; }

		public uint TotalXpRequired { get; set; }

		public string CustomLevelUpPopupText { get; set; }

		public string CustomLevelStatsText { get; set; }

		public float HealthMultiplier { get; set; }

		public float MeleeDamageMultiplier { get; set; }

		public float WeaponDamageMultiplier { get; set; }

		public List<CustomScalingBuff> CustomScaling { get; set; }

		public List<SingleUseBuff> LevelUpBonus { get; set; }

		public Level()
		{
		}

		public Level(LevelReachedInfo levelData)
			: this(levelData.LevelNumber, 0u, levelData.HealthMultiplier, 0f, 0f, null, JsonSerializer.Deserialize<List<CustomScalingBuff>>(levelData.CustomScaling))
		{
		}

		public Level(int levelNumber, uint totalXp, float healthMultiplier, float meleeMultiplier, float weaponMultiplier, List<SingleUseBuff> singleUseBuffs, List<CustomScalingBuff> customScaling, string customLevelUpPopupText = "", string customLevelStatsText = "")
		{
			LevelNumber = levelNumber;
			TotalXpRequired = totalXp;
			HealthMultiplier = healthMultiplier;
			MeleeDamageMultiplier = meleeMultiplier;
			WeaponDamageMultiplier = weaponMultiplier;
			LevelUpBonus = singleUseBuffs;
			CustomScaling = customScaling;
			CustomLevelStatsText = customLevelStatsText;
			CustomLevelUpPopupText = customLevelUpPopupText;
		}

		public override string ToString()
		{
			return $"LevelNumber {LevelNumber}";
		}
	}
	public class LevelLayout
	{
		public string Header { get; set; }

		public int GroupPersistentId { get; set; }

		public int PersistentId { get; set; }

		public string InfoText { get; set; }

		public List<Level> Levels { get; set; }

		public LevelLayout(int persistentId, string header, int groupPersistentId, string infoText, List<Level> levels)
		{
			PersistentId = persistentId;
			GroupPersistentId = groupPersistentId;
			Header = header;
			InfoText = infoText;
			Levels = levels;
		}
	}
	public class SingleUseBuff
	{
		public SingleBuff SingleBuff { get; set; }

		public float Value { get; set; }

		public SingleUseBuff(SingleBuff singleBuff, float value)
		{
			SingleBuff = singleBuff;
			Value = value;
		}
	}
}
namespace GTFuckingXP.Information.Enemies
{
	public class EnemyXp : IXpData
	{
		public uint EnemyId { get; set; }

		public string EnemyName { get; set; }

		public uint XpGain { get; set; }

		public uint DebuffXp { get; set; }

		public int LevelScalingXpDecrese { get; set; }

		public EnemyXp()
		{
		}

		public EnemyXp(uint enemyId, string enemyName, uint killXp, uint debuffXp, int levelScalingXpDecrease)
		{
			EnemyId = enemyId;
			EnemyName = enemyName;
			XpGain = killXp;
			DebuffXp = debuffXp;
			LevelScalingXpDecrese = levelScalingXpDecrease;
		}
	}
}
namespace GTFuckingXP.Information.Enemies.Scaling
{
	public class EnemyDefaultZoneLevel
	{
		public int SpawningZone { get; set; }

		public string TagText { get; set; }

		public float MaxHealthMultiplier { get; set; }

		public float ShooterDamageMultiplier { get; set; }

		public float MeleeDamageMultiplier { get; set; }

		public float PushDamageMutliplier { get; set; }

		public EnemyDefaultZoneLevel(int spawningZone, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier)
		{
			SpawningZone = spawningZone;
			MaxHealthMultiplier = hpMultiplier;
			ShooterDamageMultiplier = shooterDamageMultiplier;
			MeleeDamageMultiplier = meleeDamageMultiplier;
			PushDamageMutliplier = pushDamageMultiplier;
		}
	}
	public class EnemyLevel
	{
		public uint EnemyId { get; set; }

		public int SpawningZone { get; set; }

		public string TagText { get; set; }

		public float MaxHealthMultiplier { get; set; }

		public float ShooterDamageMultiplier { get; set; }

		public float MeleeDamageMultiplier { get; set; }

		public float PushDamageMutliplier { get; set; }

		public EnemyLevel(uint enemyId, int spawningZone, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier)
		{
			EnemyId = enemyId;
			SpawningZone = spawningZone;
			MaxHealthMultiplier = hpMultiplier;
			ShooterDamageMultiplier = shooterDamageMultiplier;
			MeleeDamageMultiplier = meleeDamageMultiplier;
			PushDamageMutliplier = pushDamageMultiplier;
		}
	}
	public class EnemyScaling
	{
		public eRundownTier Tier { get; set; }

		public int ExpeditionIndex { get; set; }

		public List<EnemyDefaultZoneLevel> DefaultScale { get; set; }

		public List<EnemyLevel> EnemyLevels { get; set; }

		public EnemyScaling(eRundownTier tier, int expeditionIndex, List<EnemyDefaultZoneLevel> zoneLevels, List<EnemyLevel> enemyLevels)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Tier = tier;
			ExpeditionIndex = expeditionIndex;
		}
	}
}
namespace GTFuckingXP.Information.Enemies.Scale
{
	public class EnemyLevels
	{
		public uint PersistendId { get; set; }

		public int EnemyId { get; set; }

		public int LevelNumber { get; set; }

		public string TagText { get; set; }

		public float MaxHealthMultiplier { get; set; }

		public float ShooterDamageMultiplier { get; set; }

		public float MeleeDamageMultiplier { get; set; }

		public float PushDamageMutliplier { get; set; }

		public EnemyLevels(uint persistentId, int enemyId, int levelNumber, string tagText, float hpMultiplier, float shooterDamageMultiplier, float meleeDamageMultiplier, float pushDamageMultiplier)
		{
			PersistendId = persistentId;
			LevelNumber = levelNumber;
			TagText = tagText;
			MaxHealthMultiplier = hpMultiplier;
			ShooterDamageMultiplier = shooterDamageMultiplier;
			MeleeDamageMultiplier = meleeDamageMultiplier;
			PushDamageMutliplier = pushDamageMultiplier;
		}
	}
	public class LevelEnemyScaler
	{
		public eRundownTier Tier { get; set; }

		public int ExpeditionIndex { get; set; }

		public List<ZoneToEnemyId> ZoneToEnemyIds { get; set; }

		public LevelEnemyScaler(eRundownTier tier, int expeditionIndex, List<ZoneToEnemyId> zoneToEnemyIds)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Tier = tier;
			ExpeditionIndex = expeditionIndex;
			ZoneToEnemyIds = zoneToEnemyIds;
		}
	}
	public class ZoneToEnemyId
	{
		public int Zone { get; set; }

		public List<uint> EnemyLevelIds { get; set; }

		public ZoneToEnemyId(int zone, List<uint> enemyLevelIds)
		{
			Zone = zone;
			EnemyLevelIds = enemyLevelIds;
		}
	}
}
namespace GTFuckingXP.Information.ClassSelector
{
	public class Group
	{
		public int PersistentId { get; set; }

		public List<int> VisibleForPlayerCount { get; set; }

		public string Name { get; set; }

		public Group(int persistentId, string name, List<int> visibleForPlayerCount)
		{
			PersistentId = persistentId;
			Name = name;
			VisibleForPlayerCount = visibleForPlayerCount;
		}
	}
}
namespace GTFuckingXP.Extensions
{
	public static class CacheApiWrapper
	{
		public const string XpModCacheName = "GTF_XP";

		internal const string LevelLayoutKey = "LevelLayout";

		internal const string CheckpointData = "XpCheckpointData";

		private const string ActiveLevelKey = "ActiveLevel";

		private const string DefaultDataBlockMaxHpKey = "MaxHpDefault";

		private const string PlayerSlotToLevelIndexMappingKey = "PlayerLevelIndexMapping";

		private const string BoosterBuffKey = "BoosterBuffKey";

		private const string AnchorDifferenceKey = "AnchorDifferenceKey";

		private const string LvlUpCallbackKey = "LvlUpCallbackKey";

		private const string ScriptsStartedCallbackKey = "ScriptsStartedCallback";

		private const string DefaultMeleeRangeKey = "DefaultMeleeRangeKey";

		private const string DefaultMeleeHitBoxKey = "DefaultMeleeHitBoxKey";

		private const string DefaultMovmentKey = "DefaultMovmentKeys";

		private const string DefaultJumpVelInitialKey = "DefaultVelInitialKey";

		private const string DefaultJumpGravityMulDefaultKey = "DefaultJumpGravityMulDefaultKey";

		private const string DefaultJumpGravityMulButtonReleasedKey = "DefaultJumpGravityMulButtonReleasedKey";

		private const string DefaultJumpGravityMulAfterPeakKey = "DefaultJumpGravityMulAfterPeakKey";

		private const string DefaultJumpGravityMulFallingKey = "DefaultJumpGravityMulFallingKey";

		private const string DefaultJumpVelocityMaxKey = "DefaultJumpVelocityMaxKey";

		public static Tscript DestroyOldCreateRegisterAndReturnComponent<Tscript>() where Tscript : Component
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			Tscript val = default(Tscript);
			if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true))
			{
				((Component)val).gameObject.SetActive(false);
				Object.Destroy((Object)(object)val);
				CacheApi.RemoveInstance<Tscript>("GTF_XP");
			}
			GameObject val2 = new GameObject("GetTheFuckingXp_Endskill");
			Object.DontDestroyOnLoad((Object)(object)val2);
			val = val2.AddComponent<Tscript>();
			CacheApi.SaveInstance<Tscript>(val, "GTF_XP");
			return val;
		}

		public static Tscript CreateRegisterAndReturnComponent<Tscript>() where Tscript : Component
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Tscript val = default(Tscript);
			if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true))
			{
				((Component)val).gameObject.SetActive(true);
				return val;
			}
			GameObject val2 = new GameObject("GetTheFuckingXp_Endskill");
			Object.DontDestroyOnLoad((Object)(object)val2);
			val = val2.AddComponent<Tscript>();
			CacheApi.SaveInstance<Tscript>(val, "GTF_XP");
			return val;
		}

		public static void KillScript<Tscript>() where Tscript : Component
		{
			Tscript val = default(Tscript);
			if (CacheApi.TryGetInstance<Tscript>(ref val, "GTF_XP", true))
			{
				((Component)val).gameObject.SetActive(false);
				Object.Destroy((Object)(object)val);
				CacheApi.RemoveInstance<Tscript>("GTF_XP");
			}
		}

		public static void SetCurrentLevelLayout(LevelLayout levelLayout)
		{
			LogManager.Debug("Set current level layout to " + levelLayout.Header + ".");
			CacheApi.SaveInformation((object)"LevelLayout", (object)levelLayout, "GTF_XP");
		}

		public static LevelLayout GetCurrentLevelLayout()
		{
			return CacheApi.GetInformation<LevelLayout>((object)"LevelLayout", "GTF_XP");
		}

		public static bool TryGetCurrentLevelLayout(out LevelLayout levelLayout)
		{
			return CacheApi.TryGetInformation<LevelLayout>((object)"LevelLayout", ref levelLayout, "GTF_XP", true);
		}

		public static void SetActiveLevel(Level newLevel, bool sendToOtherPeople = true)
		{
			LogManager.Debug($"Setting new level to {newLevel.LevelNumber}.");
			CacheApi.SaveInformation((object)"ActiveLevel", (object)newLevel, "GTF_XP");
			if (sendToOtherPeople)
			{
				NetworkApiXpManager.SendNewLevelActive(newLevel);
			}
			foreach (Action<Level> lvlUpCallBack in GetLvlUpCallBackList())
			{
				LogManager.Message("Doing some weird Lvl Up callback stuff");
				lvlUpCallBack(newLevel);
			}
		}

		public static Level GetActiveLevel()
		{
			return CacheApi.GetInformation<Level>((object)"ActiveLevel", "GTF_XP");
		}

		public static float GetDefaultMaxHp()
		{
			return CacheApi.GetInformation<float>((object)"MaxHpDefault", "GTF_XP");
		}

		public static void SetDefaultMaxHp(float defaultMaxHp)
		{
			CacheApi.SaveInformation((object)"MaxHpDefault", (object)defaultMaxHp, "GTF_XP");
		}

		public static void SetPlayerToLevelMapping(Dictionary<int, Level> playerToLevelMap)
		{
			CacheApi.SaveInformation((object)"PlayerLevelIndexMapping", (object)playerToLevelMap, "GTF_XP");
		}

		public static Dictionary<int, Level> GetPlayerToLevelMapping()
		{
			return CacheApi.GetInformation<Dictionary<int, Level>>((object)"PlayerLevelIndexMapping", "GTF_XP");
		}

		public static void SetXpStorageData(uint knownXpState)
		{
			CacheApi.SaveInformation((object)"XpCheckpointData", (object)(GetCurrentLevelLayout(), knownXpState, "GTF_XP"), "GlobalCache");
		}

		public static bool TryGetXpStorageData(out (LevelLayout levelLayout, uint totalXp) checkpointData)
		{
			return CacheApi.TryGetInformation<(LevelLayout, uint)>((object)"XpCheckpointData", ref checkpointData, "GTF_XP", true);
		}

		public static BoosterBuffs GetCurrentBoosterBuffs()
		{
			return CacheApi.GetInformation<BoosterBuffs>((object)"BoosterBuffKey", "GTF_XP");
		}

		public static void SetCurrentBoosterBuff(BoosterBuffs boosterBuff)
		{
			CacheApi.SaveInformation((object)"BoosterBuffKey", (object)boosterBuff, "GTF_XP");
		}

		public static void SetAnchorDifference(float anchorDifference)
		{
			CacheApi.SaveInformation((object)"AnchorDifferenceKey", (object)anchorDifference, "GTF_XP");
		}

		public static bool TryGetAnchorDifference(out float anchorDifference)
		{
			return CacheApi.TryGetInformation<float>((object)"AnchorDifferenceKey", ref anchorDifference, "GTF_XP", true);
		}

		public static void SetLvlUpCallBackList(List<Action<Level>> lvlUpCallbacks)
		{
			CacheApi.SaveInformation((object)"LvlUpCallbackKey", (object)lvlUpCallbacks, "GTF_XP");
		}

		public static void AddLvlUpCallback(Action<Level> lvlUpCallback)
		{
			CacheApi.GetInformation<List<Action<Level>>>((object)"LvlUpCallbackKey", "GTF_XP").Add(lvlUpCallback);
		}

		public static void SetScriptsStartedCallBackList(List<Action<Level>> lvlUpCallbacks)
		{
			CacheApi.SaveInformation((object)"ScriptsStartedCallback", (object)lvlUpCallbacks, "GTF_XP");
		}

		public static void AddScriptsStartedCallback(Action<Level> lvlUpCallback)
		{
			CacheApi.GetInformation<List<Action<Level>>>((object)"ScriptsStartedCallback", "GTF_XP").Add(lvlUpCallback);
		}

		public static List<Action<Level>> GetLvlUpCallBackList()
		{
			return CacheApi.GetInformation<List<Action<Level>>>((object)"LvlUpCallbackKey", "GTF_XP");
		}

		public static List<Action<Level>> GetScriptsStartedCallbackList()
		{
			return CacheApi.GetInformation<List<Action<Level>>>((object)"ScriptsStartedCallback", "GTF_XP");
		}

		public static void SetDefaultMeleeRange(float meleeRange)
		{
			CacheApi.SaveInformation((object)"DefaultMeleeRangeKey", (object)meleeRange, "GTF_XP");
		}

		public static void RemoveDefaultMeleeRange()
		{
			CacheApi.RemoveInformation((object)"DefaultMeleeRangeKey", "GTF_XP");
		}

		public static bool TryGetDefaultMeleeRange(out float meleeRange)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultMeleeRangeKey", ref meleeRange, "GTF_XP", true);
		}

		public static void SetDefaultMeleeHitBox(float meleeHitbox)
		{
			CacheApi.SaveInformation((object)"DefaultMeleeHitBoxKey", (object)meleeHitbox, "GTF_XP");
		}

		public static void RemoveDefaultMeleeHitBox()
		{
			CacheApi.RemoveInformation((object)"DefaultMeleeHitBoxKey", "GTF_XP");
		}

		public static bool TryGetDefaultMeleeHitBox(out float meleeHitbox)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultMeleeHitBoxKey", ref meleeHitbox, "GTF_XP", true);
		}

		public static bool TryGetDefaultMovment(out (float walk, float run, float air, float crouch) movmentData)
		{
			return CacheApi.TryGetInformation<(float, float, float, float)>((object)"DefaultMovmentKeys", ref movmentData, "GTF_XP", true);
		}

		public static void SetDefaultMovment(float walk, float run, float air, float crouch)
		{
			CacheApi.SaveInformation((object)"DefaultMovmentKeys", (object)(walk, run, air, crouch), "GTF_XP");
		}

		public static void SetDefaultJumpVelInitial(float value)
		{
			CacheApi.SaveInformation((object)"DefaultVelInitialKey", (object)value, "GTF_XP");
		}

		public static void SetDefaultJumpGravityMulDefault(float value)
		{
			CacheApi.SaveInformation((object)"DefaultJumpGravityMulDefaultKey", (object)value, "GTF_XP");
		}

		public static void SetDefaultJumpGravityMulButtonReleased(float value)
		{
			CacheApi.SaveInformation((object)"DefaultJumpGravityMulButtonReleasedKey", (object)value, "GTF_XP");
		}

		public static void SetDefaultJumpGravityMulAfterPeak(float value)
		{
			CacheApi.SaveInformation((object)"DefaultJumpGravityMulAfterPeakKey", (object)value, "GTF_XP");
		}

		public static void SetDefaultJumpGravityMulFalling(float value)
		{
			CacheApi.SaveInformation((object)"DefaultJumpGravityMulFallingKey", (object)value, "GTF_XP");
		}

		public static void SetDefaultJumpVelocityMax(float value)
		{
			CacheApi.SaveInformation((object)"DefaultJumpVelocityMaxKey", (object)value, "GTF_XP");
		}

		public static bool TryGetDefaultJumpVelInitial(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultVelInitialKey", ref value, "GTF_XP", true);
		}

		public static bool TryGetDefaultJumpGravityMulDefault(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulDefaultKey", ref value, "GTF_XP", true);
		}

		public static bool TryGetDefaultJumpGravityMulButtonReleased(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulButtonReleasedKey", ref value, "GTF_XP", true);
		}

		public static bool TryGetDefaultJumpGravityMulAfterPeak(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulAfterPeakKey", ref value, "GTF_XP", true);
		}

		public static bool TryGetDefaultJumpGravityMulFalling(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultJumpGravityMulFallingKey", ref value, "GTF_XP", true);
		}

		public static bool TryGetDefaultJumpVelocityMax(out float value)
		{
			return CacheApi.TryGetInformation<float>((object)"DefaultJumpVelocityMaxKey", ref value, "GTF_XP", true);
		}
	}
	internal static class GameObjectExtensions
	{
		public static T Instantiate<T>(this GameObject gameObject, string name) where T : Component
		{
			GameObject val = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, false);
			((Object)val).name = name;
			return val.GetComponent<T>();
		}
	}
}
namespace GTFuckingXP.Enums
{
	public enum CustomScaling
	{
		MeleeRangeMultiplier,
		MeleeHitBoxSizeMultiplier,
		MovementSpeedMultiplier,
		AntiFogSphere,
		JumpVelInitialPlus,
		JumpGravityMulDefaultPlus,
		JumpGravityMulButtonReleased,
		JumpGravityMulAfterPeakPlus,
		JumpGravityMulFallingPlus,
		JumpVerticalVelocityMaxPlus
	}
	public enum PlayerBuff
	{
		MaxHP,
		HammerDamage,
		WeaponDamage
	}
	public enum SingleBuff
	{
		Heal,
		Desinfect,
		AmmunitionMain,
		AmmunitionSpecial,
		AmmunitionTool
	}
}
namespace GTFuckingXP.Communication
{
	public static class XpApi
	{
		public static bool ReloadData()
		{
			try
			{
				ScriptManager instance = ScriptManager.Instance;
				instance.UpdateEverything();
				LevelLayout levelLayout = default(LevelLayout);
				if (CacheApi.TryGetInformation<LevelLayout>((object)"LevelLayout", ref levelLayout, "GTF_XP", true))
				{
					List<LevelLayout> instance2 = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP");
					LevelLayout currentLevelLayout = instance2.FirstOrDefault((LevelLayout it) => it.Header == levelLayout.Header);
					Level activeLevel = CacheApiWrapper.GetActiveLevel();
					CacheApiWrapper.SetCurrentLevelLayout(currentLevelLayout);
					SetCurrentLevel(activeLevel.LevelNumber, out var _);
				}
				return true;
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				return false;
			}
		}

		public static bool AddXp(uint xpAmount)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP");
				instance.AddXp(new EnemyXp(0u, "", xpAmount, xpAmount, 0), default(Vector3));
				return true;
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				return false;
			}
		}

		public static bool SetCurrentTotalXp(uint newTotalXpAmount, out int cheatedXp)
		{
			//IL_0022: 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)
			try
			{
				XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP");
				cheatedXp = (int)(newTotalXpAmount - instance.CurrentTotalXp);
				instance.CurrentTotalXp = newTotalXpAmount;
				instance.CheckForLevelThresholdReached(default(Vector3), out string currentClassName);
				CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), instance.NextLevel, instance.CurrentTotalXp, currentClassName);
				return true;
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				cheatedXp = 0;
				return false;
			}
		}

		public static bool SetCurrentLevel(int levelNumber, out int cheatedXp)
		{
			try
			{
				LevelLayout currentLevelLayout = CacheApiWrapper.GetCurrentLevelLayout();
				XpHandler instance = CacheApi.GetInstance<XpHandler>("GTF_XP");
				Level level = currentLevelLayout.Levels.First((Level it) => it.LevelNumber == levelNumber);
				instance.ChangeCurrentLevel(level, BoosterBuffManager.Instance.GetFittingBoosterBuff(currentLevelLayout.PersistentId, level.LevelNumber));
				cheatedXp = (int)(level.TotalXpRequired - instance.CurrentTotalXp);
				instance.CurrentTotalXp = level.TotalXpRequired + 1;
				instance.NextLevel = currentLevelLayout.Levels.FirstOrDefault((Level it) => it.LevelNumber == levelNumber + 1);
				CacheApi.GetInstance<XpBar>("GTF_XP").UpdateUiString(CacheApiWrapper.GetActiveLevel(), instance.NextLevel, instance.CurrentTotalXp, currentLevelLayout.Header);
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				cheatedXp = 0;
				return false;
			}
			return true;
		}

		public static bool ChangeCurrentLevelLayout(string header)
		{
			string header2 = header;
			try
			{
				LevelLayout newActiveLevelLayout = CacheApi.GetInstance<List<LevelLayout>>("GTF_XP").First((LevelLayout it) => it.Header == header2);
				return ChangeCurrentLevelLayout(newActiveLevelLayout);
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				return false;
			}
		}

		public static bool ChangeCurrentLevelLayout(LevelLayout newActiveLevelLayout)
		{
			try
			{
				bool flag = true;
				CacheApiWrapper.SetCurrentLevelLayout(newActiveLevelLayout);
				XpHandler xpHandler = default(XpHandler);
				if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
				{
					uint currentTotalXp = xpHandler.CurrentTotalXp;
					flag = SetCurrentLevel(0, out var cheatedXp) && SetCurrentTotalXp(currentTotalXp, out cheatedXp);
				}
				return true;
			}
			catch (Exception msg)
			{
				LogManager.Error(msg);
				return false;
			}
		}

		public static void AddOnLevelUpCallback(Action<Level> lvlUpCallback)
		{
			CacheApiWrapper.AddLvlUpCallback(lvlUpCallback);
		}

		public static void AddScriptsLoaded(Action<Level> scriptsLoadedCallback)
		{
			CacheApiWrapper.AddScriptsStartedCallback(scriptsLoadedCallback);
		}
	}
}
namespace GTFuckingXP.Managers
{
	[BepInPlugin("Endskill.GTFuckingXP", "GTFuckingXP", "1.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BepInExLoader : BasePlugin
	{
		public const string MODNAME = "GTFuckingXP";

		public const string AUTHOR = "Endskill";

		public const string GUID = "Endskill.GTFuckingXP";

		public const string VERSION = "1.3.1";

		public static bool RundownDevMode { get; private set; }

		public static ConfigEntry<bool> DebugMessages { get; private set; }

		public static ConfigEntry<bool> LvlUpPopups { get; private set; }

		public static ConfigEntry<bool> XpPopups { get; private set; }

		public static ConfigEntry<string> TermsOfUsage { get; internal set; }

		public static TermsOfUsage TermsOfUsageState { get; private set; }

		public static Harmony Harmony { get; private set; }

		public override void Load()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			RundownDevMode = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "RundownDev Mode", false, "This will activate the xp dev tool while in an expedition \nPress \"Delete\" to hide/show it").Value;
			DebugMessages = ((BasePlugin)this).Config.Bind<bool>("Dev Settings", "DebugMessages", false, "This settings activates/deactivates debug messages in the console for this specific plugin.");
			LvlUpPopups = ((BasePlugin)this).Config.Bind<bool>("Popups", "Lvl up popups", true, "If Lvl UP popups should be shown.");
			XpPopups = ((BasePlugin)this).Config.Bind<bool>("Popups", "XP gain popups", true, "If XP gain popups should be shown");
			TermsOfUsageState = GTFuckingXP.Information.TermsOfUsage.Declined;
			ClassInjector.RegisterTypeInIl2Cpp<XpHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<XpBar>();
			ClassInjector.RegisterTypeInIl2Cpp<DevModeTools>();
			ClassInjector.RegisterTypeInIl2Cpp<DevTools>();
			ScriptManager.Instance = new ScriptManager();
			BoosterBuffManager.Instance = new BoosterBuffManager();
			NetworkApiXpManager.Setup();
			Harmony = new Harmony("Endskill.GTFuckingXP");
			FasterPatching();
			CacheApiWrapper.SetLvlUpCallBackList(new List<Action<Level>>());
			CacheApiWrapper.SetScriptsStartedCallBackList(new List<Action<Level>>());
			InitApi.AddInitCallback((Action)delegate
			{
				ScriptManager.Instance.Initialize();
			});
		}

		private void FasterPatching()
		{
			Harmony.PatchAll(typeof(PlayerLobbyBarPatches));
			Harmony.PatchAll(typeof(GS_InLevelPatches));
			Harmony.PatchAll(typeof(EnemyDamageBasePatches));
			Harmony.PatchAll(typeof(GS_AfterLevelPatches));
			Harmony.PatchAll(typeof(PlaceNavMarkerOnGoPatches));
			Harmony.PatchAll(typeof(SnetSessionHubPatches));
		}

		private void TermsOfUsageChanged(object sender, EventArgs e)
		{
			LogManager.Debug("Accepting terms of usage while ingame.");
			UpdateTermsOfUsage();
			TermsOfUsage.SettingChanged -= TermsOfUsageChanged;
		}

		private void UpdateTermsOfUsage()
		{
			Enum.TryParse<TermsOfUsage>(TermsOfUsage.Value, out var result);
			TermsOfUsageState = result;
		}
	}
	public class BoosterBuffManager
	{
		public static BoosterBuffManager Instance { get; set; }

		public void ApplyBoosterEffects(PlayerAgent targetAgent, BoosterBuffs buffs)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			List<uint> list = default(List<uint>);
			if (!CacheApi.TryGetInformation<List<uint>>((object)targetAgent.Owner.Lookup, ref list, "GTF_XP", true))
			{
				list = new List<uint>();
			}
			foreach (uint item in list)
			{
				AgentModifierManager.ClearModifierChange(item);
			}
			list = new List<uint>();
			if (buffs != null)
			{
				foreach (KeyValuePair<AgentModifier, float> valueToBoosterEffect in buffs.ValueToBoosterEffects)
				{
					if (valueToBoosterEffect.Value != 0f)
					{
						list.Add(AgentModifierManager.AddModifierValue((Agent)(object)targetAgent, valueToBoosterEffect.Key, valueToBoosterEffect.Value - 1f, 0f));
					}
				}
			}
			CacheApi.SaveInformation((object)targetAgent.Owner.Lookup, (object)list, "GTF_XP");
		}

		public BoosterBuffs GetFittingBoosterBuff(int levelLayoutPersistendId, int levelNumber)
		{
			List<BoosterBuffs> instance = CacheApi.GetInstance<List<BoosterBuffs>>("GTF_XP");
			BoosterBuffs boosterBuffs = instance.FirstOrDefault((BoosterBuffs it) => it.ClassLayoutPersistentId == levelLayoutPersistendId && it.ActiveLevels.Contains(levelNumber));
			LogManager.Debug($"GetfittingBoosterBuff call with {levelLayoutPersistendId} as ID and {levelNumber} as levelNumber. {((boosterBuffs != null) ? "buff found" : "Buff is null")}");
			return boosterBuffs;
		}
	}
	public static class CustomScalingBuffManager
	{
		public static void ApplyCustomScalingEffects(PlayerAgent targetAgent, List<CustomScalingBuff> buffs)
		{
			if (buffs == null || buffs.Count == 0)
			{
				return;
			}
			foreach (CustomScalingBuff buff in buffs)
			{
				switch (buff.CustomBuff)
				{
				case CustomScaling.MeleeRangeMultiplier:
					if (((Agent)targetAgent).IsLocallyOwned)
					{
						MeleeArchetypeDataBlock meleeArchetypeData = ((ItemEquippable)GetLocalMeleeWeapon()).MeleeArchetypeData;
						if (!CacheApiWrapper.TryGetDefaultMeleeRange(out var meleeRange))
						{
							meleeRange = meleeArchetypeData.CameraDamageRayLength;
							CacheApiWrapper.SetDefaultMeleeRange(meleeRange);
						}
						meleeArchetypeData.CameraDamageRayLength = meleeRange * buff.Value;
					}
					break;
				case CustomScaling.MeleeHitBoxSizeMultiplier:
					if (((Agent)targetAgent).IsLocallyOwned)
					{
						MeleeArchetypeDataBlock meleeArchetypeData2 = ((ItemEquippable)GetLocalMeleeWeapon()).MeleeArchetypeData;
						if (!CacheApiWrapper.TryGetDefaultMeleeHitBox(out var meleeHitbox))
						{
							meleeHitbox = meleeArchetypeData2.AttackSphereRadius;
							CacheApiWrapper.SetDefaultMeleeHitBox(meleeHitbox);
						}
						meleeArchetypeData2.AttackSphereRadius = meleeHitbox * buff.Value;
					}
					break;
				case CustomScaling.MovementSpeedMultiplier:
					if (((Agent)targetAgent).IsLocallyOwned)
					{
						LogManager.Debug("Pre movment speed");
						PlayerDataBlock playerData = targetAgent.PlayerData;
						if (!CacheApiWrapper.TryGetDefaultMovment(out (float, float, float, float) movmentData))
						{
							movmentData.Item1 = playerData.walkMoveSpeed;
							movmentData.Item2 = playerData.runMoveSpeed;
							movmentData.Item3 = playerData.airMoveSpeed;
							movmentData.Item4 = playerData.crouchMoveSpeed;
							CacheApiWrapper.SetDefaultMovment(movmentData.Item1, movmentData.Item2, movmentData.Item3, movmentData.Item4);
						}
						playerData.walkMoveSpeed = movmentData.Item1 * buff.Value;
						playerData.runMoveSpeed = movmentData.Item2 * buff.Value;
						playerData.airMoveSpeed = movmentData.Item3 * buff.Value;
						playerData.crouchMoveSpeed = movmentData.Item4 * buff.Value;
						LogManager.Debug("Post movment speed");
					}
					break;
				case CustomScaling.JumpVelInitialPlus:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpVelInitial(out var value5))
					{
						value5 = targetAgent.PlayerData.jumpVelInitial;
						CacheApiWrapper.SetDefaultJumpVelInitial(value5);
					}
					targetAgent.PlayerData.jumpVelInitial = value5 + buff.Value;
					break;
				}
				case CustomScaling.JumpGravityMulDefaultPlus:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpGravityMulDefault(out var value4))
					{
						value4 = targetAgent.PlayerData.jumpGravityMulDefault;
						CacheApiWrapper.SetDefaultJumpGravityMulDefault(value4);
					}
					targetAgent.PlayerData.jumpGravityMulDefault = value4 + buff.Value;
					break;
				}
				case CustomScaling.JumpGravityMulButtonReleased:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpGravityMulButtonReleased(out var value2))
					{
						value2 = targetAgent.PlayerData.jumpGravityMulButtonReleased;
						CacheApiWrapper.SetDefaultJumpGravityMulButtonReleased(value2);
					}
					targetAgent.PlayerData.jumpGravityMulButtonReleased = value2 + buff.Value;
					break;
				}
				case CustomScaling.JumpGravityMulAfterPeakPlus:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpGravityMulAfterPeak(out var value6))
					{
						value6 = targetAgent.PlayerData.jumpGravityMulAfterPeak;
						CacheApiWrapper.SetDefaultJumpGravityMulAfterPeak(value6);
					}
					targetAgent.PlayerData.jumpGravityMulAfterPeak = value6 + buff.Value;
					break;
				}
				case CustomScaling.JumpGravityMulFallingPlus:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpGravityMulFalling(out var value3))
					{
						value3 = targetAgent.PlayerData.jumpGravityMulFalling;
						CacheApiWrapper.SetDefaultJumpGravityMulFalling(value3);
					}
					targetAgent.PlayerData.jumpGravityMulFalling = value3 + buff.Value;
					break;
				}
				case CustomScaling.JumpVerticalVelocityMaxPlus:
				{
					if (!CacheApiWrapper.TryGetDefaultJumpVelocityMax(out var value))
					{
						value = targetAgent.PlayerData.jumpVerticalVelocityMax;
						CacheApiWrapper.SetDefaultJumpVelocityMax(value);
					}
					targetAgent.PlayerData.jumpVerticalVelocityMax = value + buff.Value;
					break;
				}
				}
			}
		}

		private static void StartRepellerWithoutSound(FogRepeller_Sphere antiFog)
		{
		}

		private static MeleeWeaponFirstPerson GetLocalMeleeWeapon()
		{
			//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: Invalid comparison between Unknown and I4
			Enumerator<BackpackItem> enumerator = PlayerBackpackManager.LocalBackpack.BackpackItems.GetEnumerator();
			while (enumerator.MoveNext())
			{
				BackpackItem current = enumerator.Current;
				if ((int)current.Instance.pItemData.slot == 10)
				{
					LogManager.Debug("Found Melee");
					return ((Il2CppObjectBase)current.Instance).Cast<MeleeWeaponFirstPerson>();
				}
			}
			LogManager.Warn("No melee weapon found o.O?");
			throw new Exception($"There is no {typeof(MeleeWeaponFirstPerson)} item in the local backpack!");
		}
	}
	internal class LogManager
	{
		private static readonly ManualLogSource logger;

		private static readonly bool _debugMessagesActive;

		static LogManager()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			_debugMessagesActive = BepInExLoader.DebugMessages.Value;
			logger = new ManualLogSource("GTFuckingXP");
			Logger.Sources.Add((ILogSource)(object)logger);
		}

		public static void Verbose(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogInfo(msg);
			}
		}

		public static void Debug(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogDebug(msg);
			}
		}

		public static void Message(object msg)
		{
			if (_debugMessagesActive)
			{
				logger.LogMessage(msg);
			}
		}

		public static void Error(object msg)
		{
			logger.LogError(msg);
		}

		public static void Warn(object msg)
		{
			logger.LogWarning(msg);
		}
	}
	public static class NetworkApiXpManager
	{
		private const string _sendXpString = "ThisSeemsLikeItComesFromTheRandomXpMod...";

		private const string _levelStatsDistribution = "ReachedSentLevel_XP";

		private const string _receiveStaticXp = "XpModTriesToGiveYouSomeHalfAssedXP";

		private const string _undistributedXp = "XpModGivesYouSomeXpWhereYouHadNotToDoAnything";

		private const string _sendBoosterNetworkString = "MyNewBoostersEffectFromTheXpMod";

		public static void Setup()
		{
			NetworkAPI.RegisterEvent<GtfoApiXpInfo>("ThisSeemsLikeItComesFromTheRandomXpMod...", (Action<ulong, GtfoApiXpInfo>)ReceiveXp);
			NetworkAPI.RegisterEvent<LevelReachedInfo>("ReachedSentLevel_XP", (Action<ulong, LevelReachedInfo>)ReceiveLevelReached);
			NetworkAPI.RegisterEvent<StaticXpInfo>("XpModTriesToGiveYouSomeHalfAssedXP", (Action<ulong, StaticXpInfo>)ReceiveStaticXp);
			NetworkAPI.RegisterEvent<BoosterInfo>("MyNewBoostersEffectFromTheXpMod", (Action<ulong, BoosterInfo>)ReceiveBoosterBuffs);
			NetworkAPI.RegisterEvent<GtfoApiXpInfo>("XpModGivesYouSomeXpWhereYouHadNotToDoAnything", (Action<ulong, GtfoApiXpInfo>)ReceiveHalfAssedXp);
		}

		public static void ReceiveXp(ulong snetPlayer, GtfoApiXpInfo xpData)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			LogManager.Debug("Received xp networking package");
			XpHandler xpHandler = default(XpHandler);
			if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
			{
				xpHandler.AddXp(xpData, new Vector3(xpData.PositionX, xpData.PositionY, xpData.PositionZ));
			}
		}

		public static void ReceiveHalfAssedXp(ulong snetPlayer, GtfoApiXpInfo xpData)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			XpHandler xpHandler = default(XpHandler);
			if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
			{
				xpHandler.AddXp(xpData, new Vector3(xpData.PositionX, xpData.PositionY, xpData.PositionZ), xpData.ForceDebuffXp, "<#888>");
			}
		}

		public static void ReceiveStaticXp(ulong snetPlayer, StaticXpInfo xpInfo)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			LogManager.Debug("Received static xp networking pckage");
			XpHandler xpHandler = default(XpHandler);
			if (CacheApi.TryGetInstance<XpHandler>(ref xpHandler, "GTF_XP", true))
			{
				xpHandler.AddXp(xpInfo, xpInfo.Position, forceDebuffXp: false, "<#F30>");
			}
		}

		public static void ReceiveLevelReached(ulong snetPlayer, LevelReachedInfo levelData)
		{
			LogManager.Debug("Receive level reached info");
			SNet_Player val = default(SNet_Player);
			if (!SNet.TryGetPlayer(snetPlayer, ref val))
			{
				return;
			}
			List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel;
			Enumerator<PlayerAgent> enumerator = playerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (current.PlayerSlotIndex == val.PlayerSlotIndex())
				{
					Level level = new Level(levelData);
					float num = level.HealthMultiplier * CacheApiWrapper.GetDefaultMaxHp();
					LogManager.Debug($"Setting HP of {((Object)current).name} to {num}");
					((Dam_SyncedDamageBase)current.Damage).HealthMax = num;
					CustomScalingBuffManager.ApplyCustomScalingEffects(current, level.CustomScaling);
					CacheApiWrapper.GetPlayerToLevelMapping()[current.PlayerSlotIndex] = level;
				}
			}
		}

		internal static void ReceiveBoosterBuffs(ulong snetPlayer, BoosterInfo newInfo)
		{
			SNet_Player val = default(SNet_Player);
			if (!SNet.TryGetPlayer(snetPlayer, ref val))
			{
				return;
			}
			List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel;
			Enumerator<PlayerAgent> enumerator = playerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (current.PlayerSlotIndex == val.PlayerSlotIndex())
				{
					BoosterBuffManager.Instance.ApplyBoosterEffects(current, newInfo);
				}
			}
		}

		public static void SendReceiveXp(SNet_Player receiver, EnemyXp xpData, Vector3 position, bool forceDebuffXp)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			NetworkAPI.InvokeEvent<GtfoApiXpInfo>("ThisSeemsLikeItComesFromTheRandomXpMod...", new GtfoApiXpInfo(xpData.XpGain, xpData.DebuffXp, xpData.LevelScalingXpDecrese, position, forceDebuffXp), receiver, (SNet_ChannelType)2);
		}

		public static void SendHalfAssedXp(EnemyXp xpData, Vector3 position, bool forceDebuffXp)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			NetworkAPI.InvokeEvent<GtfoApiXpInfo>("XpModGivesYouSomeXpWhereYouHadNotToDoAnything", new GtfoApiXpInfo(xpData.XpGain, xpData.DebuffXp, xpData.LevelScalingXpDecrese, position, forceDebuffXp), (SNet_ChannelType)2);
		}

		public static void SendNewLevelActive(Level newLevel)
		{
			string customScaling = JsonSerializer.Serialize((newLevel.CustomScaling == null) ? new List<CustomScalingBuff>() : newLevel.CustomScaling);
			NetworkAPI.InvokeEvent<LevelReachedInfo>("ReachedSentLevel_XP", new LevelReachedInfo(newLevel.LevelNumber, newLevel.HealthMultiplier, customScaling), (SNet_ChannelType)2);
		}

		public static void SendBoosterStatsReached(BoosterInfo boosterInfo)
		{
			NetworkAPI.InvokeEvent<BoosterInfo>("MyNewBoostersEffectFromTheXpMod", boosterInfo, (SNet_ChannelType)2);
		}

		public static void SendStaticXpInfo(SNet_Player receiver, uint xpGain, uint debuffXp, int levelScalingDecrease, Vector3 position)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			NetworkAPI.InvokeEvent<StaticXpInfo>("XpModTriesToGiveYouSomeHalfAssedXP", new StaticXpInfo(xpGain, debuffXp, levelScalingDecrease, position), receiver, (SNet_ChannelType)2);
		}
	}
	public class ScriptManag

BepInEx/plugins/MadnessLights.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Diagnostics;
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 BepInEx.Unity.IL2CPP.Utils.Collections;
using GTFO.API;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MadnessLights")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MadnessLights")]
[assembly: AssemblyTitle("MadnessLights")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MadnessLights
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("MadnessLights", "MadnessLights", "0.0.1")]
	public class Plugin : BasePlugin
	{
		private class MadnessLights : MonoBehaviour
		{
			public bool _valot;

			public ManualLogSource Log;

			public void Initialize()
			{
				foreach (LG_Light item in Object.FindObjectsOfType<LG_Light>())
				{
					CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(SetLightIntensity(item)), (Action)null);
				}
			}

			private void Start()
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 0, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin is loaded!");
				}
				log.LogInfo(val);
			}

			private void Update()
			{
				if (Input.GetKeyDown((KeyCode)56))
				{
					_valot = !_valot;
					Log.LogInfo((object)("flashing lights manual activation: " + (_valot ? "enabled" : "disabled")));
				}
			}

			private IEnumerator SetLightIntensity(LG_Light obj)
			{
				bool hirnudirection = true;
				float hirnuintensity = 0.02f;
				((Object)obj).GetInstanceID();
				float origintensity = obj.m_intensity;
				Color origcolor = obj.m_color;
				Color hirnuvari = Color.red;
				while (true)
				{
					if (_valot | WorldEventManager.GetCondition(16))
					{
						obj.ChangeColor(hirnuvari);
						while (_valot | WorldEventManager.GetCondition(16))
						{
							if (hirnuintensity > 0.1f && hirnudirection)
							{
								hirnudirection = false;
								hirnuintensity = 0.09f;
							}
							if (hirnuintensity < 0.01f && !hirnudirection)
							{
								hirnudirection = true;
							}
							if (hirnudirection)
							{
								hirnuintensity += 0.003f;
							}
							if (!hirnudirection)
							{
								hirnuintensity -= 0.003f;
							}
							obj.ChangeIntensity(hirnuintensity);
							yield return (object)new WaitForSeconds(0.04f);
						}
					}
					obj.ChangeColor(origcolor);
					obj.ChangeIntensity(origintensity);
					yield return (object)new WaitForSeconds(0.5f);
				}
			}
		}

		public override void Load()
		{
			MadnessLights madnessLights = ((BasePlugin)this).AddComponent<MadnessLights>();
			EventAPI.OnExpeditionStarted += madnessLights.Initialize;
			madnessLights.Log = ((BasePlugin)this).Log;
		}
	}
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "MadnessLights";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = null;

		public const string SemVer = "1.0.0";

		public const string GitRevShort = null;

		public const string GitRevLong = null;

		public const string GitBranch = null;

		public const string GitTag = null;

		public const bool GitIsDirty = false;
	}
}