Decompiled source of 985646TESTING v1.0.8

plugins/GTFO-API.dll

Decompiled 2 years ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
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.Bootstrap;
using BepInEx.IL2CPP;
using BepInEx.IL2CPP.Hook;
using BepInEx.IL2CPP.Utils;
using BepInEx.Logging;
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 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 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 = "")]
[assembly: AssemblyCompany("GTFO-API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.1")]
[assembly: AssemblyInformationalVersion("0.3.1+git4b21c34-main")]
[assembly: AssemblyProduct("GTFO-API")]
[assembly: AssemblyTitle("GTFO-API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.1.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 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()
		{
			AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)OnAssetsLoaded);
			OnImplReady += LoadAssetBundles;
		}

		private static void LoadAssetBundles()
		{
			string path = Path.Combine(Paths.ConfigPath, "Assets", "AssetBundles");
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}
			string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
			if (files.Length == 0)
			{
				return;
			}
			for (int i = 0; i < files.Length; i++)
			{
				try
				{
					LoadAndRegisterAssetBundle(files[i]);
				}
				catch (Exception ex)
				{
					APILogger.Warn("AssetAPI", $"Failed to load asset bundle '{files[i]}' ({ex.Message})");
				}
			}
			AssetAPI.OnAssetBundlesLoaded?.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>();
		}
	}
	[API("Network")]
	public static class NetworkAPI
	{
		internal class CachedEvent
		{
			public string EventName { get; set; }

			public Type Type { get; set; }

			public object OnReceive { 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,
					Type = typeof(T),
					OnReceive = onReceive
				});
			}
			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());
		}

		private static Il2CppStructArray<byte> MakeBytes<T>(string eventName, T payload) where T : struct
		{
			return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakePacketBytes(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);
					}
				}
			}
		}
	}
	[BepInPlugin("dev.gtfomodding.gtfo-api", "GTFO-API", "0.3.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();
			AssetAPI.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.3.1";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "git4b21c34-main";

		public const string SemVer = "0.3.1+git4b21c34-main";

		public const string GitRevShort = "4b21c34";

		public const string GitRevLong = "4b21c34e6e7b0ca87cc4ae60bd12120654e36fe1";

		public const string GitBranch = "main";

		public const string GitTag = "0.3.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 void StartCoroutine(IEnumerator routine)
		{
			CoroutineDispatcher_Impl.Instance.RunCoroutine(routine);
		}

		public static void StartInLevelCoroutine(IEnumerator routine)
		{
			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.PluginPath, "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 void RunCoroutine(IEnumerator routine)
		{
			MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
		}

		[HideFromIl2Cpp]
		internal void RunInLevelCoroutine(IEnumerator routine)
		{
			if (!GameStateManager.IsInExpedition)
			{
				APILogger.Error("CoroutineDispatcher", "Cannot run InLevelCoroutine while you're not in level!");
				return;
			}
			Coroutine item = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
			m_InLevelCoroutines.Add(item);
			m_HasInLevelCoroutines = true;
		}
	}
	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 GameData { get; internal set; } = new ApiStatusInfo();


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


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


		public static ApiStatusInfo Prefab { 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 = 18374688137539712817uL;
	}
}
namespace GTFO.API.Patches
{
	[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(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;
			try
			{
				PluginWhitelistInfo[] array = FetchPluginWhitelist();
				if (array.Length == 0)
				{
					throw null;
				}
				foreach (PluginInfo loadedPlugin in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.Values)
				{
					if (loadedPlugin.Metadata.GUID == "dev.gtfomodding.gtfo-api")
					{
						continue;
					}
					using SHA256 sHA = SHA256.Create();
					string s = $"{loadedPlugin.Metadata.GUID}|{loadedPlugin.Metadata.Version}|{loadedPlugin.Metadata.Name}|{Path.GetFileName(loadedPlugin.Location)}|{loadedPlugin.Instance.GetType().Assembly.FullName}";
					byte[] bytes = Encoding.UTF8.GetBytes(s);
					sHA.TransformBlock(bytes, 0, bytes.Length, null, 0);
					byte[] array2 = File.ReadAllBytes(loadedPlugin.Location);
					sHA.TransformFinalBlock(array2, 0, array2.Length);
					string checksum = StringUtils.FromByteArrayAsHex(sHA.Hash);
					if (!array.Any((PluginWhitelistInfo x) => x.Name == loadedPlugin.Metadata.Name && x.GUID == loadedPlugin.Metadata.GUID && x.Version == ((object)loadedPlugin.Metadata.Version).ToString() && x.Checksum == checksum))
					{
						throw null;
					}
				}
			}
			catch
			{
				goto IL_01be;
			}
			goto IL_02c6;
			IL_01be:
			GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u);
			if (block == null || block.RundownIdToLoad != 1)
			{
				APILogger.Verbose("GameDataInit_Patches", $"RundownIdToLoad was {block.RundownIdToLoad}. Setting to 1");
				GameDataBlockBase<RundownDataBlock>.RemoveBlockByID(1u);
				RundownDataBlock block2 = GameDataBlockBase<RundownDataBlock>.GetBlock(block.RundownIdToLoad);
				if (block2 != null)
				{
					((GameDataBlockBase<RundownDataBlock>)(object)block2).persistentID = 1u;
					((GameDataBlockBase<RundownDataBlock>)(object)block2).name = "MOVEDBYAPI_" + ((GameDataBlockBase<RundownDataBlock>)(object)block2).name;
					block2.UseTierUnlockRequirements = false;
					RemoveRequirementFromList(block2.TierA);
					RemoveRequirementFromList(block2.TierB);
					RemoveRequirementFromList(block2.TierC);
					RemoveRequirementFromList(block2.TierD);
					RemoveRequirementFromList(block2.TierE);
					GameDataBlockBase<RundownDataBlock>.RemoveBlockByID(block.RundownIdToLoad);
					GameDataBlockBase<RundownDataBlock>.AddBlock(block2, -1);
					block.RundownIdToLoad = 1u;
				}
				else
				{
					APILogger.Error("GameDataInit_Patches", "GameSetupDataBlock points to an invalid Rundown Id");
				}
			}
			goto IL_02c6;
			IL_02c6:
			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.ConfigPath, "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(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, 196, 40, 195
		};

		public abstract byte[] CodeCave { get; }

		public unsafe abstract void* MethodPtr { get; }

		public abstract string JmpStartSig { get; }

		public abstract string JmpStartMask { get; }

		public abstract uint TrampolineSize { get; }

		public abstract T To { get; }

		public unsafe virtual void Apply()
		{
			void* ptr = MemoryUtils.FindSignatureInBlock(MethodPtr, 4096uL, JmpStartSig, JmpStartMask, 0uL);
			void* end = (void*)((ulong)ptr + (ulong)TrampolineSize);
			void* ptr2 = Kernel32.VirtualAlloc(null, (ulong)(s_CodeCaveHeader.Length + CodeCave.Length + s_CodeCaveFooter.Length), 12288u, 64u);
			fixed (byte* source = s_CodeCaveHeader)
			{
				MSVCRT.memcpy(ptr2, source, s_CodeCaveHeader.Length);
			}
			fixed (byte* source2 = CodeCave)
			{
				MSVCRT.memcpy((void*)((ulong)ptr2 + (ulong)s_CodeCaveHeader.Length), source2, CodeCave.Length);
			}
			void* ptr3 = (void*)((long)ptr2 + (long)s_CodeCaveHeader.Length + CodeCave.Length);
			fixed (byte* source3 = s_CodeCaveFooter)
			{
				MSVCRT.memcpy(ptr3, source3, s_CodeCaveFooter.Length);
			}
			*(long*)((ulong)ptr3 + 2uL) = Marshal.GetFunctionPointerForDelegate(To).ToInt64();
			APILogger.Verbose("NativePatch", $"Method: 0x{MethodPtr:X2}, Trampoline: 0x{ptr:X2}, Code Cave: 0x{ptr2:X2}");
			MemoryUtils.CreateTrampolineBetween(ptr, end, ptr2);
		}
	}
}
namespace GTFO.API.JSON
{
	public static class JsonSerializer
	{
		private static JsonSerializerOptions s_DefaultSerializerSettings;

		public static JsonSerializerOptions DefaultSerializerSettings
		{
			get
			{
				if (s_DefaultSerializerSettings == null)
				{
					s_DefaultSerializerSettings = new JsonSerializerOptions
					{
						ReadCommentHandling = JsonCommentHandling.Skip,
						IncludeFields = false,
						PropertyNameCaseInsensitive = true,
						WriteIndented = true,
						IgnoreReadOnlyProperties = true
					};
					s_DefaultSerializerSettings.Converters.Add(new JsonStringEnumConverter());
					s_DefaultSerializerSettings.Converters.Add(new Vector2Converter());
					s_DefaultSerializerSettings.Converters.Add(new Vector3Converter());
					s_DefaultSerializerSettings.Converters.Add(new ColorConverter());
				}
				return s_DefaultSerializerSettings;
			}
		}

		public static string Serialize(object value, JsonSerializerOptions options = null)
		{
			if (options == null)
			{
				options = DefaultSerializerSettings;
			}
			return System.Text.Json.JsonSerializer.Serialize(value, options);
		}

		public static T Deserialize<T>(string json, JsonSerializerOptions options = null)
		{
			if (options == null)
			{
				options = DefaultSerializerSettings;
			}
			return System.Text.Json.JsonSerializer.Deserialize<T>(json, options);
		}
	}
}
namespace GTFO.API.JSON.Converters
{
	public sealed class ColorConverter : JsonConverter<Color>
	{
		public override bool HandleNull => false;

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

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

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

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

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

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

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

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

		public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y} {value.z})");
		}
	}
}
namespace GTFO.API.Extensions
{
	public static class ListExtensions
	{
		public static List<T> ToIl2Cpp<T>(this List<T> list)
		{
			List<T> val = new List<T>(list.Count);
			for (int i = 0; i < list.Count; i++)
			{
				val.Add(list[i]);
			}
			return val;
		}
	}
}
namespace GTFO.API.Components
{
	public class ConsumableInstance : ItemWrapped
	{
		public ConsumableInstance(IntPtr hdl)
			: base(hdl)
		{
		}
	}
}
namespace GTFO.API.Attributes
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
	internal class APIAttribute : Attribute
	{
		public string Name;

		public APIAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
	internal class Il2CppInterfaceAttribute : Attribute
	{
		public Type Type;

		public Il2CppInterfaceAttribute(Type type)
		{
			Type = type;
		}
	}
}
namespace GTFO.API.Impl
{
	internal class AssetAPI_Impl : MonoBehaviour
	{
		private static AssetAPI_Impl s_Instance;

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

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

		private void Awake()
		{
			s_Instance = this;
			APIStatus.Asset.Ready = true;
			foreach (KeyValuePair<string, Object> item in AssetAPI.s_RegistryCache)
			{
				RegisterAsset(item.Key, item.Value);
			}
			AssetAPI.s_RegistryCache.Clear();
			AssetAPI.InvokeImplReady();
		}

		public void RegisterAsset(string name, Object gameObject)
		{
			string text = name.ToUpper();
			if (AssetShardManager.s_loadedAssetsLookup.ContainsKey(text))
			{
				throw new ArgumentException("The asset with " + name + " has already been registered.", "name");
			}
			APILogger.Verbose("AssetAPI_Impl", "Registering asset: " + name);
			AssetShardManager.s_loadedAssetsLookup.Add(text, gameObject);
		}
	}
	internal interface INetworkingEventInfo
	{
		string Name { get; }

		Type EventType { get; }

		int EventTypeSize { get; }

		byte[] EventNameBytes { get; }

		void InvokeOnReceive(ulong sender, object payload);
	}
	internal class NetworkingEventInfo<T> : INetworkingEventInfo where T : struct
	{
		public string Name { get; set; }

		public Action<ulong, T> OnReceive { get; set; }

		public Type EventType { get; set; }

		public int EventTypeSize { get; set; }

		public byte[] EventNameBytes { get; set; }

		public void InvokeOnReceive(ulong sender, object payload)
		{
			if (payload is T)
			{
				T arg = (T)payload;
				OnReceive?.Invoke(sender, arg);
			}
		}
	}
	internal class NetworkAPI_Impl : MonoBehaviour
	{
		public ushort m_ReplicatorKey = 65533;

		public ulong m_Signature = 18374688137539712817uL;

		private readonly Dictionary<string, INetworkingEventInfo> m_Events = new Dictionary<string, INetworkingEventInfo>();

		private static readonly byte[] s_MagicBytes = Encoding.ASCII.GetBytes("GAPI_KSQK");

		private static NetworkAPI_Impl s_Instance;

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

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

		private void Awake()
		{
			s_Instance = this;
			APIStatus.Network.Ready = true;
			foreach (KeyValuePair<string, NetworkAPI.CachedEvent> item in NetworkAPI.s_EventCache)
			{
				typeof(NetworkAPI_Impl).GetMethod("RegisterEvent").MakeGenericMethod(item.Value.Type).Invoke(this, new object[2]
				{
					item.Key,
					item.Value.OnReceive
				});
			}
			NetworkAPI.s_EventCache.Clear();
		}

		internal unsafe static void XORPacket(ref byte[] packetBytes, ulong versionSig, int offset)
		{
			fixed (byte* ptr = packetBytes)
			{
				XORPacketImpl(ptr + offset, (uint)(packetBytes.Length - offset), (byte*)(&versionSig));
			}
		}

		internal unsafe static void XORPacketImpl(byte* pPacket, uint packetLength, byte* pVersion)
		{
			for (int i = 0; i < packetLength; i++)
			{
				pPacket[i] ^= pVersion[i % 8];
			}
		}

		[HideFromIl2Cpp]
		public void HandlePacket(string eventName, ulong senderId, byte[] packetData, int startIndex = 0)
		{
			INetworkingEventInfo networkingEventInfo = m_Events[eventName];
			Type eventType = networkingEventInfo.EventType;
			XORPacket(ref packetData, m_Signature, startIndex);
			int num = Marshal.SizeOf(eventType);
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.Copy(packetData, startIndex, intPtr, num);
			object payload = Marshal.PtrToStructure(intPtr, eventType);
			Marshal.FreeHGlobal(intPtr);
			networkingEventInfo.InvokeOnReceive(senderId, payload);
		}

		[HideFromIl2Cpp]
		public void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
		{
			if (EventExists(eventName))
			{
				throw new ArgumentException($"Type {typeof(T)} is a generic and cannot be registered.", "eventName");
			}
			if (typeof(T).IsGenericType)
			{
				throw new ArgumentException("Generic type is not allowed to register", "T");
			}
			NetworkingEventInfo<T> value = new NetworkingEventInfo<T>
			{
				Name = eventName,
				OnReceive = onReceive,
				EventType = typeof(T),
				EventTypeSize = Marshal.SizeOf<T>(),
				EventNameBytes = Encoding.UTF8.GetBytes(eventName)
			};
			m_Events.Add(eventName, value);
		}

		[HideFromIl2Cpp]
		public bool EventExists(string eventName)
		{
			return m_Events.ContainsKey(eventName);
		}

		[HideFromIl2Cpp]
		public byte[] MakePacketBytes<T>(string eventName, T payload) where T : struct
		{
			if (!m_Events.TryGetValue(eventName, out var value))
			{
				throw new ArgumentException("An event with the name " + eventName + " was not registered.", "eventName");
			}
			if (value.EventType != typeof(T))
			{
				throw new ArgumentException("Payload type was incorrect! expecting: " + typeof(T).FullName, "eventName");
			}
			byte[] eventNameBytes = value.EventNameBytes;
			int num = 21 + eventNameBytes.Length + value.EventTypeSize;
			IntPtr intPtr;
			IntPtr intPtr2 = (intPtr = Marshal.AllocHGlobal(num));
			Marshal.WriteInt16(intPtr, (short)m_ReplicatorKey);
			intPtr += 2;
			Marshal.Copy(s_MagicBytes, 0, intPtr, 9);
			intPtr += 9;
			Marshal.WriteInt64(intPtr, (long)m_Signature);
			intPtr += 8;
			Marshal.WriteInt16(intPtr, (short)eventNameBytes.Length);
			intPtr += 2;
			Marshal.Copy(eventNameBytes, 0, intPtr, eventNameBytes.Length);
			intPtr += eventNameBytes.Length;
			Marshal.StructureToPtr(payload, intPtr, fDeleteOld: true);
			byte[] packetBytes = new byte[num];
			Marshal.Copy(intPtr2, packetBytes, 0, num);
			Marshal.FreeHGlobal(intPtr2);
			XORPacket(ref packetBytes, m_Signature, 21 + eventNameBytes.Length);
			return packetBytes;
		}
	}
}

plugins/SamUtils.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using CellMenu;
using DropServer;
using DropServer.BoosterImplants;
using DropServer.VanityItems;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Threading.Tasks;
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("SamUtils")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SamUtils")]
[assembly: AssemblyTitle("SamUtils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace SamUtils;

internal class InventoryPatches
{
	public unsafe delegate void UpdateItems(IntPtr _this, IntPtr data, Il2CppMethodInfo* methodInfo);

	[HarmonyPatch(typeof(DropServerClientAPIViaPlayFab), "GetInventoryPlayerDataAsync")]
	public static class DropServerClientAPI_GetInventoryPlayerDataAsync_Patch
	{
		public static bool Prefix(GetInventoryPlayerDataRequest request, ref Task<GetInventoryPlayerDataResult> __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			VanityItemPlayerData val = new VanityItemPlayerData(ClassInjector.DerivedConstructorPointer<VanityItemPlayerData>());
			val.Items = new Il2CppReferenceArray<VanityItem>(0L);
			BoosterImplantPlayerData val2 = new BoosterImplantPlayerData(ClassInjector.DerivedConstructorPointer<BoosterImplantPlayerData>());
			val2.Advanced = EmptyCat();
			val2.Basic = EmptyCat();
			val2.Specialized = EmptyCat();
			GetInventoryPlayerDataResult val3 = new GetInventoryPlayerDataResult(ClassInjector.DerivedConstructorPointer<GetInventoryPlayerDataResult>())
			{
				Boosters = val2,
				VanityItems = val
			};
			__result = Task.FromResult<GetInventoryPlayerDataResult>(val3);
			return false;
		}
	}

	internal List<INativeDetour> _detours = new List<INativeDetour>();

	private UpdateItems _patchMethod;

	private UpdateItems _originalUpdateItems;

	internal unsafe void ApplyNative()
	{
		_patchMethod = UpdateItemsPatch;
		_detours.Add(INativeDetour.CreateAndApply<UpdateItems>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<VanityItemInventory>("UpdateItems", typeof(void).FullName, false, new string[1] { typeof(VanityItemPlayerData).FullName }), _patchMethod, ref _originalUpdateItems));
	}

	public unsafe void UpdateItemsPatch(IntPtr _this, IntPtr data, Il2CppMethodInfo* methodInfo)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		_originalUpdateItems(_this, data, methodInfo);
		VanityItemInventory val = new VanityItemInventory(_this);
		if (val.m_backednItems == null)
		{
			val.m_backednItems = new List<VanityItem>(0);
		}
		foreach (VanityItemsTemplateDataBlock allBlock in GameDataBlockBase<VanityItemsTemplateDataBlock>.GetAllBlocks())
		{
			VanityItem val2 = new VanityItem(ClassInjector.DerivedConstructorPointer<VanityItem>());
			val2.publicName = allBlock.publicName;
			val2.type = allBlock.type;
			val2.prefab = allBlock.prefab;
			val2.flags = (VanityItemFlags)3;
			val2.id = ((GameDataBlockBase<VanityItemsTemplateDataBlock>)(object)allBlock).persistentID;
			val.m_backednItems.Add(val2);
		}
	}

	private static Category EmptyCat()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		return new Category(ClassInjector.DerivedConstructorPointer<Category>())
		{
			Inventory = new Il2CppReferenceArray<BoosterImplantInventoryItem>(0L)
		};
	}
}
internal static class LobbyPatches
{
	[HarmonyPatch(typeof(CM_PlayerLobbyBar), "SetupFromPage")]
	public static class CM_PlayerLobbyBar_SetupFromPage_Patch
	{
		public static void Postfix(CM_PlayerLobbyBar __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			__instance.m_boosterImplantAlign.position = new Vector3(10000f, 0f, 0f);
		}
	}
}
[BepInPlugin("samutils", "SamUtils", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
	public const string PLUGIN_GUID = "samutils";

	public const string PLUGIN_NAME = "SamUtils";

	public const string PLUGIN_VERSION = "1.0.0";

	private static Plugin _instance;

	private readonly Harmony _harmony = new Harmony("samutils");

	private static InventoryPatches _patches;

	public override void Load()
	{
		_instance = this;
		_patches = new InventoryPatches();
		_patches.ApplyNative();
		_harmony.PatchAll(typeof(LobbyPatches.CM_PlayerLobbyBar_SetupFromPage_Patch));
		_harmony.PatchAll(typeof(InventoryPatches.DropServerClientAPI_GetInventoryPlayerDataAsync_Patch));
	}

	internal static void LogMsg(string v)
	{
		((BasePlugin)_instance).Log.LogMessage((object)v);
	}
}

plugins/Oxygen.dll

Decompiled 2 years ago
using System;
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 System.Text.Json.Serialization;
using AK;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using CellMenu;
using DropServer;
using DropServer.BoosterImplants;
using DropServer.VanityItems;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using GameEvent;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Threading.Tasks;
using LevelGeneration;
using Localization;
using MTFO.Managers;
using Microsoft.CodeAnalysis;
using Oxygen.Components;
using Oxygen.Config;
using Oxygen.Utils;
using Oxygen.Utils.PartialData;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Oxygen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Oxygen")]
[assembly: AssemblyTitle("Oxygen")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Oxygen
{
	[BepInPlugin("Inas.Oxygen", "Oxygen", "1.2.1")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__Setup;

			public static Action <1>__OnBuildDone;

			public static Action <2>__OnLevelCleanup;

			public static Action <3>__Setup;

			public static Action <4>__OnLevelCleanup;

			public static Action <5>__OnBuildStart;

			public static Action <6>__OnLevelCleanup;

			public static LiveEditEventHandler <7>__Listener_FileChanged1;
		}

		public const string MODNAME = "Oxygen";

		public const string AUTHOR = "Inas";

		public const string GUID = "Inas.Oxygen";

		public const string VERSION = "1.2.1";

		public static readonly string OXYGEN_CONFIG_PATH = Path.Combine(ConfigManager.CustomPath, "Oxygen");

		public static Dictionary<uint, OxygenBlock> lookup = new Dictionary<uint, OxygenBlock>();

		private static LiveEditListener listener = null;

		public override void Load()
		{
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			if (!Directory.Exists(OXYGEN_CONFIG_PATH))
			{
				Directory.CreateDirectory(OXYGEN_CONFIG_PATH);
				StreamWriter streamWriter = File.CreateText(Path.Combine(OXYGEN_CONFIG_PATH, "Template.json"));
				streamWriter.WriteLine(ConfigManager.Serialize(new OxygenConfig()));
				streamWriter.Flush();
				streamWriter.Close();
			}
			ClassInjector.RegisterTypeInIl2Cpp<AirManager>();
			LevelAPI.OnBuildStart += AirManager.Setup;
			LevelAPI.OnBuildDone += AirManager.OnBuildDone;
			LevelAPI.OnLevelCleanup += AirManager.OnLevelCleanup;
			ClassInjector.RegisterTypeInIl2Cpp<AirBar>();
			LevelAPI.OnBuildStart += AirBar.Setup;
			LevelAPI.OnLevelCleanup += AirBar.OnLevelCleanup;
			ClassInjector.RegisterTypeInIl2Cpp<AirPlane>();
			LevelAPI.OnBuildStart += AirPlane.OnBuildStart;
			LevelAPI.OnLevelCleanup += AirPlane.OnLevelCleanup;
			new Harmony("Inas.Oxygen").PatchAll();
			foreach (string item in Directory.EnumerateFiles(OXYGEN_CONFIG_PATH, "*.json", SearchOption.AllDirectories))
			{
				ConfigManager.Load<OxygenConfig>(item, out var config);
				foreach (OxygenBlock block in config.Blocks)
				{
					foreach (uint fogSetting in block.FogSettings)
					{
						if (!lookup.ContainsKey(fogSetting))
						{
							lookup.Add(fogSetting, block);
						}
					}
				}
			}
			listener = LiveEdit.CreateListener(OXYGEN_CONFIG_PATH, "*.json", true);
			LiveEditListener obj = listener;
			object obj2 = <>O.<7>__Listener_FileChanged1;
			if (obj2 == null)
			{
				LiveEditEventHandler val = Listener_FileChanged1;
				<>O.<7>__Listener_FileChanged1 = val;
				obj2 = (object)val;
			}
			obj.FileChanged += (LiveEditEventHandler)obj2;
		}

		private static void Listener_FileChanged1(LiveEditEventArgs e)
		{
			Log.Warning("LiveEdit File Changed: " + e.FullPath + ".");
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				foreach (OxygenBlock block in ConfigManager.Deserialize<OxygenConfig>(content).Blocks)
				{
					foreach (uint fogSetting in block.FogSettings)
					{
						if (lookup.ContainsKey(fogSetting))
						{
							lookup.Remove(fogSetting);
						}
						lookup.Add(fogSetting, block);
						Log.Warning($"Replaced OxygenConfig for FogSetting: {fogSetting}.");
					}
				}
				if (GameStateManager.IsInExpedition)
				{
					AirManager.Current.UpdateAirConfig(AirManager.Current.FogSetting(), LiveEditForceUpdate: true);
				}
			});
		}
	}
}
namespace Oxygen.Utils
{
	internal static class Extension
	{
		public static T Instantiate<T>(this GameObject gameObject, string name) where T : Component
		{
			GameObject obj = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, false);
			((Object)obj).name = name;
			return obj.GetComponent<T>();
		}
	}
	internal class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				return new LocalizedText
				{
					Id = 0u,
					UntranslatedText = @string
				};
			}
			case JsonTokenType.Number:
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			default:
				throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	internal static class Log
	{
		private static ManualLogSource source;

		static Log()
		{
			source = Logger.CreateLogSource("Oxygen");
		}

		public static void Debug(object msg)
		{
			source.LogDebug(msg);
		}

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

		public static void Fatal(object msg)
		{
			source.LogFatal(msg);
		}

		public static void Info(object msg)
		{
			source.LogInfo(msg);
		}

		public static void Message(object msg)
		{
			source.LogMessage(msg);
		}

		public static void Warning(object msg)
		{
			source.LogWarning(msg);
		}
	}
}
namespace Oxygen.Utils.PartialData
{
	public static class MTFOPartialDataUtil
	{
		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

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

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

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Log.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
			}
		}
	}
}
namespace Oxygen.Patches
{
	[HarmonyPatch]
	internal class Patches_Dam_PlayerDamageLocal
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveNoAirDamage")]
		public static bool Pre_ReceiveNoAirDamage(Dam_PlayerDamageLocal __instance, pMiniDamageData data)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax);
			((Dam_PlayerDamageBase)__instance).m_nextRegen = Clock.Time + ((Dam_PlayerDamageBase)__instance).Owner.PlayerData.healthRegenStartDelayAfterDamage;
			if (((Agent)((Dam_PlayerDamageBase)__instance).Owner).IsLocallyOwned)
			{
				DramaManager.CurrentState.OnLocalDamage(num);
				GameEventManager.PostEvent((eGameEvent)13, ((Dam_PlayerDamageBase)__instance).Owner, num, "", (Dictionary<string, string>)null);
			}
			else
			{
				DramaManager.CurrentState.OnTeammatesDamage(num);
			}
			if (((Dam_PlayerDamageBase)__instance).IgnoreAllDamage)
			{
				return false;
			}
			if (SNet.IsMaster && !((Dam_SyncedDamageBase)__instance).RegisterDamage(num))
			{
				((Dam_SyncedDamageBase)__instance).SendSetHealth(((Dam_SyncedDamageBase)__instance).Health);
			}
			__instance.Hitreact(((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax), Vector3.zero, true, false, false);
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveBulletDamage")]
		public static void Post_ReceiveBulletDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveMeleeDamage")]
		public static void Post_ReceiveMeleeDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveFireDamage")]
		public static void Post_ReceiveFireDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveShooterProjectileDamage")]
		public static void Post_ReceiveShooterProjectileDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveTentacleAttackDamage")]
		public static void Post_ReceiveTentacleAttackDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceivePushDamage")]
		public static void Post_ReceivePushDamage()
		{
			AirManager.Current.ResetHealthToRegen();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveSetDead")]
		public static void Post_ReceiveSetDead()
		{
			AirManager.Current.ResetHealthToRegen();
		}
	}
	[HarmonyPatch(typeof(EnvironmentStateManager), "UpdateFog")]
	internal class EnvironmentStateManager_UpdateFog
	{
		public static void Prefix(EnvironmentStateManager __instance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)AirManager.Current == (Object)null)
			{
				return;
			}
			FogState val = ((Il2CppArrayBase<FogState>)(object)__instance.m_stateReplicator.State.FogStates)[__instance.m_latestKnownLocalDimensionCreationIndex];
			if (val.FogDataID != 0)
			{
				AirManager.Current.UpdateAirConfig(val.FogDataID);
				if (!AirManager.Current.HasAirConfig())
				{
					AirManager.Current.StopInfectionLoop();
				}
			}
		}
	}
	[HarmonyPatch(typeof(FogRepeller_Sphere), "StartRepelling")]
	internal class FogRepeller_Sphere_StartRepelling
	{
		public static void Postfix(ref FogRepeller_Sphere __instance)
		{
			if (__instance.m_infectionShield != null)
			{
				EffectVolumeManager.UnregisterVolume((EffectVolume)(object)__instance.m_infectionShield);
				((EffectVolume)__instance.m_infectionShield).contents = (eEffectVolumeContents)0;
				EffectVolumeManager.RegisterVolume((EffectVolume)(object)__instance.m_infectionShield);
			}
		}
	}
	[HarmonyPatch(typeof(LocalPlayerAgentSettings), "UpdateBlendTowardsTargetFogSetting")]
	internal class LocalPlayerAgentSettings_UpdateBlendTowardsTargetFogSetting
	{
		public static void Postfix(LocalPlayerAgentSettings __instance, float amount)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!AirManager.Current.HasAirConfig())
			{
				AirPlane.Current.Unregister();
			}
			else
			{
				if (__instance.m_targetFogSettings == null || !SNet.LocalPlayer.HasPlayerAgent)
				{
					return;
				}
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				if ((Object)(object)localPlayerAgent.FPSCamera == (Object)null)
				{
					return;
				}
				AirPlane current = AirPlane.Current;
				if (!((Object)(object)current == (Object)null) && RundownManager.ExpeditionIsStarted)
				{
					float num = 0f;
					Dimension val = default(Dimension);
					if (Dimension.GetDimension(((Agent)localPlayerAgent).DimensionIndex, ref val))
					{
						num = val.GroundY;
					}
					PreLitVolume prelitVolume = localPlayerAgent.FPSCamera.PrelitVolume;
					((EffectVolume)current.airPlane).invert = (double)prelitVolume.m_densityHeightMaxBoost > (double)prelitVolume.m_fogDensity;
					((EffectVolume)current.airPlane).contents = (eEffectVolumeContents)1;
					((EffectVolume)current.airPlane).modification = (eEffectVolumeModification)0;
					((EffectVolume)current.airPlane).modificationScale = AirManager.Current.AirLoss();
					current.airPlane.lowestAltitude = prelitVolume.m_densityHeightAltitude + num;
					current.airPlane.highestAltitude = prelitVolume.m_densityHeightAltitude + prelitVolume.m_densityHeightRange + num;
					AirPlane.Current.Register();
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAgent), "ReceiveModification")]
	internal class PlayerAgent_ReceiveModification
	{
		public static void Prefix(PlayerAgent __instance, ref EV_ModificationData data)
		{
			if (AirManager.Current.HasAirConfig())
			{
				if ((double)data.health != 0.0)
				{
					AirManager.Current.RemoveAir(data.health);
				}
				else
				{
					AirManager.Current.AddAir();
				}
				data.health = 0f;
			}
		}
	}
}
namespace Oxygen.Config
{
	public class ConfigManager
	{
		private static readonly JsonSerializerOptions s_SerializerOptions;

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

		public static string Serialize<T>(T value)
		{
			return JsonSerializer.Serialize(value, s_SerializerOptions);
		}

		static ConfigManager()
		{
			s_SerializerOptions = new JsonSerializerOptions
			{
				AllowTrailingCommas = true,
				ReadCommentHandling = JsonCommentHandling.Skip,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true
			};
			s_SerializerOptions.Converters.Add(new JsonStringEnumConverter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
				Log.Message("PartialData Support Found!");
			}
			else
			{
				s_SerializerOptions.Converters.Add(new LocalizedTextConverter());
			}
		}

		public static void Load<T>(string file, out T config) where T : new()
		{
			if (file.Length < ".json".Length)
			{
				config = default(T);
				return;
			}
			if (file.Substring(file.Length - ".json".Length) != ".json")
			{
				file += ".json";
			}
			file = File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "Oxygen", file));
			config = Deserialize<T>(file);
		}
	}
	public class AirText
	{
		public float x { get; set; }

		public float y { get; set; }

		public LocalizedText Text { get; set; }
	}
	public class OxygenConfig
	{
		public List<OxygenBlock> Blocks { get; set; } = new List<OxygenBlock>
		{
			new OxygenBlock()
		};

	}
	public class OxygenBlock
	{
		public float AirLoss { get; set; }

		public float AirGain { get; set; } = 1f;


		public float DamageTime { get; set; } = 1f;


		public float DamageAmount { get; set; }

		public bool ShatterGlass { get; set; }

		public float ShatterAmount { get; set; }

		public float DamageThreshold { get; set; } = 0.1f;


		public bool AlwaysDisplayAirBar { get; set; }

		public float HealthRegenProportion { get; set; } = 1f;


		public float TimeToStartHealthRegen { get; set; } = 3f;


		public float TimeToCompleteHealthRegen { get; set; } = 5f;


		public AirText AirText { get; set; }

		public List<uint> FogSettings { get; set; } = new List<uint> { 0u };

	}
}
namespace Oxygen.Components
{
	public class AirBar : MonoBehaviour
	{
		public static AirBar Current;

		private TextMeshPro m_airText;

		private TextMeshPro m_airTextLocalization;

		private float m_airTextX;

		private float m_airTextY;

		private float m_airTextZ;

		private RectTransform m_air1;

		private RectTransform m_air2;

		private SpriteRenderer m_airBar1;

		private SpriteRenderer m_airBar2;

		private float m_airWidth = 100f;

		private float m_barHeightMin = 3f;

		private float m_barHeightMax = 9f;

		private Color m_airLow = new Color(0f, 0.5f, 0.5f);

		private Color m_airHigh = new Color(0f, 0.3f, 0.8f);

		public AirBar(IntPtr value)
			: base(value)
		{
		}//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)


		public static void Setup()
		{
			if ((Object)(object)Current == (Object)null)
			{
				Current = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus).gameObject.AddComponent<AirBar>();
				Current.Init();
			}
		}

		private void Init()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_airText == (Object)null)
			{
				m_airText = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_healthText).gameObject.Instantiate<TextMeshPro>("AirText");
				TextMeshPro airText = m_airText;
				((TMP_Text)airText).fontSize = ((TMP_Text)airText).fontSize / 1.25f;
				m_airText.transform.Translate(0f, -30f, 0f);
			}
			if ((Object)(object)m_airTextLocalization == (Object)null)
			{
				m_airTextLocalization = ((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_pulseText).gameObject.Instantiate<TextMeshPro>("AirText Localization");
				((Behaviour)m_airTextLocalization).enabled = true;
				m_airTextLocalization.transform.Translate(300f - m_airWidth, -45f, 0f);
				m_airTextX = m_airTextLocalization.transform.position.x;
				m_airTextY = m_airTextLocalization.transform.position.y;
				m_airTextZ = m_airTextLocalization.transform.position.z;
			}
			if ((Object)(object)m_air1 == (Object)null)
			{
				m_air1 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health1).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Right");
				((Component)m_air1).transform.Translate(0f, -30f, 0f);
				SpriteRenderer component = ((Component)((Transform)m_air1).GetChild(0)).GetComponent<SpriteRenderer>();
				component.size = new Vector2(m_airWidth, component.size.y);
				m_airBar1 = ((Component)((Transform)m_air1).GetChild(1)).GetComponent<SpriteRenderer>();
				((Renderer)((Component)((Transform)m_air1).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false;
			}
			if ((Object)(object)m_air2 == (Object)null)
			{
				m_air2 = ((Component)((Component)GuiManager.Current.m_playerLayer.m_playerStatus.m_health2).gameObject.transform.parent).gameObject.Instantiate<RectTransform>("AirFill Left");
				((Component)m_air2).transform.Translate(0f, 30f, 0f);
				SpriteRenderer component2 = ((Component)((Transform)m_air2).GetChild(0)).GetComponent<SpriteRenderer>();
				component2.size = new Vector2(m_airWidth, component2.size.y);
				m_airBar2 = ((Component)((Transform)m_air2).GetChild(1)).GetComponent<SpriteRenderer>();
				((Renderer)((Component)((Transform)m_air2).GetChild(2)).GetComponent<SpriteRenderer>()).enabled = false;
			}
			UpdateAirBar(1f);
			SetVisible(vis: false);
		}

		public void UpdateAirBar(float air)
		{
			SetAirPercentageText(air);
			SetAirBar(m_airBar1, air);
			SetAirBar(m_airBar2, air);
		}

		private void SetAirBar(SpriteRenderer bar, float val)
		{
			//IL_001b: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			bar.size = new Vector2(val * m_airWidth, Mathf.Lerp(m_barHeightMin, m_barHeightMax, val));
			bar.color = Color.Lerp(m_airLow, m_airHigh, val);
		}

		private void SetAirPercentageText(float val)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Color color = Color.Lerp(m_airLow, m_airHigh, val);
			((TMP_Text)m_airText).text = "O<size=75%>2</size>";
			((Graphic)m_airText).color = color;
			((TMP_Text)m_airText).ForceMeshUpdate(true, false);
			((Graphic)m_airTextLocalization).color = color;
			((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false);
		}

		public void UpdateAirText(OxygenBlock config)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (config != null)
			{
				string text = LocalizedText.op_Implicit(config.AirText.Text);
				float x = config.AirText.x;
				float y = config.AirText.y;
				((TMP_Text)m_airTextLocalization).text = text;
				((TMP_Text)m_airTextLocalization).ForceMeshUpdate(true, false);
				CoroutineManager.BlinkIn(((Component)m_airTextLocalization).gameObject, 0f);
				m_airTextLocalization.transform.SetPositionAndRotation(new Vector3(m_airTextX + x, m_airTextY + y, m_airTextZ), m_airTextLocalization.transform.rotation);
			}
		}

		public void SetVisible(bool vis)
		{
			((Component)m_airText).gameObject.SetActive(vis);
			((Component)m_airTextLocalization).gameObject.SetActive(vis);
			((Component)m_air1).gameObject.SetActive(vis);
			((Component)m_air2).gameObject.SetActive(vis);
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.SetVisible(vis: false);
			}
		}
	}
	public class AirManager : MonoBehaviour
	{
		public static AirManager Current;

		public PlayerAgent m_playerAgent;

		private HUDGlassShatter m_hudGlass;

		private Dam_PlayerDamageBase Damage;

		public OxygenBlock config;

		private uint fogSetting;

		private FogSettingsDataBlock fogSettingDB;

		private float airAmount = 1f;

		private float damageTick;

		private float glassShatterAmount;

		private bool m_isInInfectionLoop;

		private bool isRegeningHealth;

		private float healthToRegen;

		private float healthRegenTick;

		private float tickUntilHealthRegenHealthStart;

		private readonly float regenHealthTickInterval = 0.25f;

		private float healthRegenAmountPerInterval;

		internal bool PlayerShouldCough;

		private readonly float CoughPerLoss = 0.1f;

		private float CoughLoss;

		public AirManager(IntPtr value)
			: base(value)
		{
		}

		public static void Setup()
		{
			if ((Object)(object)Current == (Object)null)
			{
				Current = ((Component)PlayerManager.Current.m_localPlayerAgentInLevel).gameObject.AddComponent<AirManager>();
			}
		}

		public static void OnBuildDone()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.m_playerAgent = PlayerManager.GetLocalPlayerAgent();
				Current.m_hudGlass = ((Component)Current.m_playerAgent.FPSCamera).GetComponent<HUDGlassShatter>();
				Current.Damage = ((Component)Current.m_playerAgent).gameObject.GetComponent<Dam_PlayerDamageBase>();
				Current.UpdateAirConfig(RundownManager.ActiveExpedition.Expedition.FogSettings);
				AirBar.Current.UpdateAirText(Current.config);
			}
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				if (Current.m_isInInfectionLoop)
				{
					Current.StopInfectionLoop();
				}
				Current.config = null;
				Current.fogSetting = 0u;
				Current.fogSettingDB = null;
				Current.airAmount = 0f;
				Current.damageTick = 0f;
				Current.glassShatterAmount = 0f;
				Current.healthToRegen = 0f;
				Current.m_playerAgent = null;
				Current.m_hudGlass = null;
				Current.Damage = null;
			}
		}

		private void Update()
		{
			if (!RundownManager.ExpeditionIsStarted)
			{
				return;
			}
			if (!HasAirConfig())
			{
				AirBar.Current.SetVisible(vis: false);
				return;
			}
			if (airAmount == 1f)
			{
				if (config.AlwaysDisplayAirBar)
				{
					AirBar.Current.SetVisible(vis: true);
				}
				else
				{
					AirBar.Current.SetVisible(vis: false);
				}
			}
			else
			{
				AirBar.Current.SetVisible(vis: true);
			}
			if (airAmount <= config.DamageThreshold)
			{
				damageTick += Time.deltaTime;
				if (damageTick > config.DamageTime && ((Dam_SyncedDamageBase)Damage).Health > 0f && ((Agent)m_playerAgent).Alive)
				{
					AirDamage();
				}
				isRegeningHealth = false;
			}
			else if (healthToRegen > 0f)
			{
				tickUntilHealthRegenHealthStart += Time.deltaTime;
				if (tickUntilHealthRegenHealthStart > config.TimeToStartHealthRegen)
				{
					if (healthRegenAmountPerInterval == 0f)
					{
						healthRegenAmountPerInterval = healthToRegen * (regenHealthTickInterval / config.TimeToCompleteHealthRegen);
					}
					RegenHealth();
					if (!isRegeningHealth)
					{
						Damage.m_nextRegen = Clock.Time + config.TimeToStartHealthRegen + config.TimeToCompleteHealthRegen;
						isRegeningHealth = true;
					}
				}
			}
			else
			{
				isRegeningHealth = false;
			}
		}

		public void AddAir()
		{
			if (HasAirConfig())
			{
				float airGain = config.AirGain;
				airAmount = Mathf.Clamp01(airAmount + airGain);
				AirBar.Current.UpdateAirBar(airAmount);
				if (fogSettingDB.Infection <= 0f && m_isInInfectionLoop)
				{
					StopInfectionLoop();
				}
			}
		}

		public void RemoveAir(float amount)
		{
			if (HasAirConfig())
			{
				amount = config.AirLoss;
				airAmount = Mathf.Clamp01(airAmount - amount);
				AirBar.Current.UpdateAirBar(airAmount);
				if (fogSettingDB.Infection <= 0f && amount > 0f)
				{
					StartInfectionLoop();
				}
			}
		}

		public void AirDamage()
		{
			float health = ((Dam_SyncedDamageBase)Damage).Health;
			float num = config.DamageAmount;
			if (num > health)
			{
				num = ((health > 0f) ? (health - 0.001f) : 0f);
			}
			((Dam_SyncedDamageBase)Damage).NoAirDamage(num);
			if (config.ShatterGlass)
			{
				glassShatterAmount += config.ShatterAmount;
				m_hudGlass.SetGlassShatterProgression(glassShatterAmount);
			}
			damageTick = 0f;
			tickUntilHealthRegenHealthStart = 0f;
			healthRegenAmountPerInterval = 0f;
			healthToRegen += num * config.HealthRegenProportion;
			CoughLoss += num;
			if (CoughLoss > CoughPerLoss)
			{
				PlayerShouldCough = true;
				CoughLoss = 0f;
			}
		}

		public void RegenHealth()
		{
			if (healthToRegen <= 0f)
			{
				return;
			}
			tickUntilHealthRegenHealthStart = config.TimeToStartHealthRegen;
			healthRegenTick += Time.deltaTime;
			if (healthRegenTick > regenHealthTickInterval)
			{
				float num = healthRegenAmountPerInterval;
				if (num >= healthToRegen)
				{
					num = healthToRegen;
					healthToRegen = 0f;
					tickUntilHealthRegenHealthStart = 0f;
					healthRegenAmountPerInterval = 0f;
					isRegeningHealth = false;
				}
				else
				{
					healthToRegen -= num;
				}
				((Dam_SyncedDamageBase)Damage).AddHealth(num, (Agent)(object)m_playerAgent);
				healthRegenTick = 0f;
			}
		}

		public void UpdateAirConfig(uint fogsetting, bool LiveEditForceUpdate = false)
		{
			if (fogsetting != 0 && (fogsetting != fogSetting || LiveEditForceUpdate))
			{
				if (Plugin.lookup.ContainsKey(fogsetting))
				{
					config = Plugin.lookup[fogsetting];
				}
				else if (Plugin.lookup.ContainsKey(0u))
				{
					config = Plugin.lookup[0u];
				}
				else
				{
					config = null;
					airAmount = 1f;
				}
				fogSetting = fogsetting;
				fogSettingDB = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(fogsetting);
				if (GameStateManager.IsInExpedition)
				{
					AirBar.Current.UpdateAirText(config);
				}
			}
		}

		public void ResetHealthToRegen()
		{
			healthRegenTick = 0f;
			healthToRegen = 0f;
			tickUntilHealthRegenHealthStart = 0f;
		}

		public float AirLoss()
		{
			if (config != null)
			{
				return config.AirLoss;
			}
			return 0f;
		}

		public bool AlwaysDisplayAirBar()
		{
			if (config != null)
			{
				return config.AlwaysDisplayAirBar;
			}
			return false;
		}

		public uint FogSetting()
		{
			return fogSetting;
		}

		public float HealthToRegen()
		{
			return healthToRegen;
		}

		public string AirText()
		{
			return LocalizedText.op_Implicit((config == null) ? null : config.AirText.Text);
		}

		public float AirTextX()
		{
			if (config != null)
			{
				return config.AirText.x;
			}
			return 0f;
		}

		public float AirTextY()
		{
			if (config != null)
			{
				return config.AirText.y;
			}
			return 0f;
		}

		public bool HasAirConfig()
		{
			return config != null;
		}

		public void StartInfectionLoop()
		{
			if (!m_isInInfectionLoop)
			{
				m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_START, true);
				m_isInInfectionLoop = true;
			}
		}

		public void StopInfectionLoop()
		{
			if (m_isInInfectionLoop)
			{
				if ((Object)(object)m_playerAgent != (Object)null && m_playerAgent.Sound != null)
				{
					m_playerAgent.Sound.Post(EVENTS.INFECTION_EFFECT_LOOP_STOP, true);
				}
				m_isInInfectionLoop = false;
			}
		}
	}
	public class AirPlane : MonoBehaviour
	{
		public static AirPlane Current;

		public EV_Plane airPlane;

		private bool isAirPlaneRegistered;

		public AirPlane(IntPtr value)
			: base(value)
		{
		}

		public static void OnBuildStart()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if ((Object)(object)Current == (Object)null)
			{
				Current = ((Component)LocalPlayerAgentSettings.Current).gameObject.AddComponent<AirPlane>();
			}
			Current.airPlane = new EV_Plane();
			uint num = RundownManager.ActiveExpedition.Expedition.FogSettings;
			if (num == 0)
			{
				num = 21u;
			}
			OxygenBlock oxygenBlock = (Plugin.lookup.ContainsKey(num) ? Plugin.lookup[num] : ((!Plugin.lookup.ContainsKey(0u)) ? null : Plugin.lookup[0u]));
			FogSettingsDataBlock block = GameDataBlockBase<FogSettingsDataBlock>.GetBlock(num);
			((EffectVolume)Current.airPlane).invert = block.DensityHeightMaxBoost > block.FogDensity;
			((EffectVolume)Current.airPlane).contents = (eEffectVolumeContents)1;
			((EffectVolume)Current.airPlane).modification = (eEffectVolumeModification)0;
			Current.airPlane.lowestAltitude = block.DensityHeightAltitude;
			Current.airPlane.highestAltitude = block.DensityHeightAltitude + block.DensityHeightRange;
			if (oxygenBlock != null)
			{
				((EffectVolume)Current.airPlane).modificationScale = oxygenBlock.AirLoss;
				Current.Register();
			}
		}

		public static void OnLevelCleanup()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				Current.Unregister();
				Current.isAirPlaneRegistered = false;
				Current.airPlane = null;
			}
		}

		public void Register()
		{
			if (airPlane != null && !isAirPlaneRegistered)
			{
				EffectVolumeManager.RegisterVolume((EffectVolume)(object)airPlane);
				isAirPlaneRegistered = true;
			}
		}

		public void Unregister()
		{
			if (airPlane != null && isAirPlaneRegistered)
			{
				EffectVolumeManager.UnregisterVolume((EffectVolume)(object)airPlane);
				isAirPlaneRegistered = false;
			}
		}
	}
}
namespace Oxygen.Utils.SU
{
	internal class InventoryPatches
	{
		public unsafe delegate void UpdateItems(IntPtr _this, IntPtr data, Il2CppMethodInfo* methodInfo);

		[HarmonyPatch(typeof(DropServerClientAPIViaPlayFab), "GetInventoryPlayerDataAsync")]
		public static class DropServerClientAPI_GetInventoryPlayerDataAsync_Patch
		{
			public static bool Prefix(GetInventoryPlayerDataRequest request, ref Task<GetInventoryPlayerDataResult> __result)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Expected O, but got Unknown
				VanityItemPlayerData val = new VanityItemPlayerData(ClassInjector.DerivedConstructorPointer<VanityItemPlayerData>());
				val.Items = new Il2CppReferenceArray<VanityItem>(0L);
				BoosterImplantPlayerData val2 = new BoosterImplantPlayerData(ClassInjector.DerivedConstructorPointer<BoosterImplantPlayerData>());
				val2.Advanced = EmptyCat();
				val2.Basic = EmptyCat();
				val2.Specialized = EmptyCat();
				GetInventoryPlayerDataResult val3 = new GetInventoryPlayerDataResult(ClassInjector.DerivedConstructorPointer<GetInventoryPlayerDataResult>())
				{
					Boosters = val2,
					VanityItems = val
				};
				__result = Task.FromResult<GetInventoryPlayerDataResult>(val3);
				return false;
			}
		}

		internal List<INativeDetour> _detours = new List<INativeDetour>();

		private UpdateItems _patchMethod;

		private UpdateItems _originalUpdateItems;

		internal unsafe void ApplyNative()
		{
			_patchMethod = UpdateItemsPatch;
			_detours.Add(INativeDetour.CreateAndApply<UpdateItems>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<VanityItemInventory>("UpdateItems", typeof(void).FullName, false, new string[1] { typeof(VanityItemPlayerData).FullName }), _patchMethod, ref _originalUpdateItems));
		}

		public unsafe void UpdateItemsPatch(IntPtr _this, IntPtr data, Il2CppMethodInfo* methodInfo)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			_originalUpdateItems(_this, data, methodInfo);
			VanityItemInventory val = new VanityItemInventory(_this);
			if (val.m_backednItems == null)
			{
				val.m_backednItems = new List<VanityItem>(0);
			}
			foreach (VanityItemsTemplateDataBlock allBlock in GameDataBlockBase<VanityItemsTemplateDataBlock>.GetAllBlocks())
			{
				VanityItem val2 = new VanityItem(ClassInjector.DerivedConstructorPointer<VanityItem>());
				val2.publicName = allBlock.publicName;
				val2.type = allBlock.type;
				val2.prefab = allBlock.prefab;
				val2.flags = (VanityItemFlags)3;
				val2.id = ((GameDataBlockBase<VanityItemsTemplateDataBlock>)(object)allBlock).persistentID;
				val.m_backednItems.Add(val2);
			}
		}

		private static Category EmptyCat()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return new Category(ClassInjector.DerivedConstructorPointer<Category>())
			{
				Inventory = new Il2CppReferenceArray<BoosterImplantInventoryItem>(0L)
			};
		}
	}
	internal static class LobbyPatches
	{
		[HarmonyPatch(typeof(CM_PlayerLobbyBar), "SetupFromPage")]
		public static class CM_PlayerLobbyBar_SetupFromPage_Patch
		{
			public static void Postfix(CM_PlayerLobbyBar __instance)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				__instance.m_boosterImplantAlign.position = new Vector3(10000f, 0f, 0f);
			}
		}
	}
	[BepInPlugin("sameutils", "SamUtils", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		public const string PLUGIN_GUID = "sameutils";

		public const string PLUGIN_NAME = "SamUtils";

		public const string PLUGIN_VERSION = "1.0.0";

		private static Plugin _instance;

		private readonly Harmony _harmony = new Harmony("sameutils");

		private static InventoryPatches _patches;

		private static bool _initialLoad = true;

		public override void Load()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			_instance = this;
			if (_initialLoad)
			{
				_harmony.Patch((MethodBase)typeof(GameDataInit).GetMethod("Initialize"), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("OnAfterGameDataInit")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_initialLoad = false;
				return;
			}
			_patches = new InventoryPatches();
			_patches.ApplyNative();
			_harmony.PatchAll(typeof(LobbyPatches.CM_PlayerLobbyBar_SetupFromPage_Patch));
			_harmony.PatchAll(typeof(InventoryPatches.DropServerClientAPI_GetInventoryPlayerDataAsync_Patch));
		}

		public static void OnAfterGameDataInit()
		{
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.Any((KeyValuePair<string, PluginInfo> p) => p.Value.Metadata.GUID == "samutils"))
			{
				((BasePlugin)_instance).Load();
			}
		}

		internal static void LogMsg(string v)
		{
			((BasePlugin)_instance).Log.LogMessage((object)v);
		}
	}
}