Decompiled source of Tartarus v1.1.3

plugins/GTFO-API.dll

Decompiled 3 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using AIGraph;
using AssetShards;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils;
using GTFO.API.Attributes;
using GTFO.API.Components;
using GTFO.API.Extensions;
using GTFO.API.Impl;
using GTFO.API.JSON;
using GTFO.API.JSON.Converters;
using GTFO.API.Native;
using GTFO.API.Resources;
using GTFO.API.Utilities;
using GTFO.API.Utilities.Impl;
using GTFO.API.Wrappers;
using GameData;
using Gear;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using ItemSetup;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;
using UnityEngine.Analytics;

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

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

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

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

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

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

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

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

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

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

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

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

		public static ApiStatusInfo Status => APIStatus.Asset;

		public static event Action OnStartupAssetsLoaded;

		public static event Action OnAssetBundlesLoaded;

		public static event Action OnImplReady;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static event Action OnManagersSetup;

		public static event Action OnExpeditionStarted;

		public static event Action OnAssetsLoaded;

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

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

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

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

		public static event Action OnGameDataInitialized;

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

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

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

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

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

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

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

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

		private static int s_LatestExpIndex = -1;

		public static ApiStatusInfo Status => APIStatus.Level;

		public static event LevelDataUpdateEvent OnLevelDataUpdated;

		public static event LevelSelectedEvent OnLevelSelected;

		public static event Action OnBuildStart;

		public static event Action OnBuildDone;

		public static event Action OnEnterLevel;

		public static event Action OnLevelCleanup;

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

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

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

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

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

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

		public eRundownKey rundownType;

		public string rundownKey;

		public eRundownTier tier;

		public int expeditionIndex;

		public int hostIDSeed;

		public int sessionSeed;

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

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

			private TextDBOptions m_Options;

			public uint? TextBlockId { get; private set; }

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

			private bool TryGetStringInLanguage(Language language, [NotNullWhen(true)] out string? value)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Expected I4, but got Unknown
				int num = language - 1;
				value = m_ValuesByLanguage[num];
				return value != null;
			}

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

			private string GetStringForTextDB(Language language, string key, FallbackValueOptions options)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetString(language, options, out string value))
				{
					return value;
				}
				ValidateUseKey(key, language, options, "GenerateTextDB");
				return key;
			}

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

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

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

			public string GetString(Language language, string key, FallbackValueOptions options)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetString(language, options, out string value))
				{
					return value;
				}
				ValidateUseKey(key, language, options, "GetString");
				return key;
			}

			public string FormatString(Language language, string key, FallbackValueOptions options, object?[] args)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetString(language, options, out string value))
				{
					return string.Format(value, args);
				}
				ValidateUseKey(key, language, options, "FormatString");
				return key;
			}

			public bool HasValueInLanguage(Language language)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				ValidateLanguage(language, "language");
				return m_ValuesByLanguage[language - 1] != null;
			}

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

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

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

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

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

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

			public FallbackValueFlags Flags { get; }

			public Language? FallbackLanguage { get; }

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

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

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

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

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

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

			public bool Equals(FallbackValueOptions other)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				if (Flags == other.Flags)
				{
					return FallbackLanguage == other.FallbackLanguage;
				}
				return false;
			}

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

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

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

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

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

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

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

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

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

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

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

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

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

		public struct TextDBOptions
		{
			private FallbackValueOptions? m_FallbackOptions;

			private uint? m_CharacterMetadataId;

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

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

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

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

		private static bool s_GameDataInitialized = false;

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

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

		public static ApiStatusInfo Status => APIStatus.Localization;

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

		public static event Action? OnLanguageChange;

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

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

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

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

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

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

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

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

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

		public static string GetString(string key, FallbackValueOptions options)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			ValidateLocalizationKey(key, "key");
			Language currentLanguage = CurrentLanguage;
			if (!s_Entries.TryGetValue(key, out Entry value))
			{
				ValidateUseKey(key, currentLanguage, options, "GetString");
				return key;
			}
			return value.GetString(currentLanguage, key, options);
		}

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

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

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

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

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

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

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

		public static void AddEntry(string key, Language language, string value, TextDBOptions? textDataBlockOptions = null)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			ValidateLocalizationKey(key, "key");
			ValidateLanguage(language, "language");
			if (value == null)
			{
				value = string.Empty;
			}
			bool exists;
			ref Entry valueRefOrAddDefault = ref CollectionsMarshal.GetValueRefOrAddDefault(s_Entries, key, out exists);
			if (valueRefOrAddDefault == null)
			{
				valueRefOrAddDefault = new Entry();
			}
			valueRefOrAddDefault.AddValue(language, value);
			if (textDataBlockOptions.HasValue && !exists)
			{
				s_EntriesToGenerateTextDBs.Add(key);
				if (s_GameDataInitialized)
				{
					valueRefOrAddDefault.GenerateTextDataBlock(key, textDataBlockOptions.Value);
				}
			}
		}

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

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

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

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

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

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

		private static void UpdateTextDataBlock(TextDataBlock block, Language language, string text)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected I4, but got Unknown
			switch (language - 1)
			{
			case 0:
				block.English = text;
				break;
			case 1:
				block.French = LanguageData.op_Implicit(text);
				break;
			case 2:
				block.Italian = LanguageData.op_Implicit(text);
				break;
			case 3:
				block.German = LanguageData.op_Implicit(text);
				break;
			case 4:
				block.Spanish = LanguageData.op_Implicit(text);
				break;
			case 5:
				block.Russian = LanguageData.op_Implicit(text);
				break;
			case 6:
				block.Portuguese_Brazil = LanguageData.op_Implicit(text);
				break;
			case 7:
				block.Polish = LanguageData.op_Implicit(text);
				break;
			case 8:
				block.Japanese = LanguageData.op_Implicit(text);
				break;
			case 9:
				block.Korean = LanguageData.op_Implicit(text);
				break;
			case 10:
				block.Chinese_Traditional = LanguageData.op_Implicit(text);
				break;
			case 11:
				block.Chinese_Simplified = LanguageData.op_Implicit(text);
				break;
			}
		}
	}
	[API("Network")]
	public static class NetworkAPI
	{
		internal class CachedEvent
		{
			public string EventName { get; set; }

			public Type PayloadType { get; set; }

			public object OnReceive { get; set; }

			public bool IsFreeSize { get; set; }
		}

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

		public static ApiStatusInfo Status => APIStatus.Network;

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

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

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

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

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

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

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

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

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

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

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

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

		public static ApiStatusInfo Status => APIStatus.Prefab;

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

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

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

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

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

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

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

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

		public static event Action OnSoundBanksLoaded;

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

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

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

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

		public const string Version = "0.4.1";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "git1e8fe81-main";

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

		public const string GitRevShort = "1e8fe81";

		public const string GitRevLong = "1e8fe816dac645ea837fe046d35f0b1ec044f6db";

		public const string GitBranch = "main";

		public const string GitTag = "0.4.0";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		string TerminalItemKey { get; set; }

		string OverrideCode { get; set; }

		Vector3 LocatorBeaconPosition { get; set; }

		AIG_CourseNode SpawnNode { get; set; }

		bool ShowInFloorInventory { get; set; }

		string FloorItemLocation { get; set; }

		eFloorInventoryObjectType FloorItemType { get; set; }

		eFloorInventoryObjectStatus FloorItemStatus { get; set; }

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

		void Setup(string key);

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

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

		string InteractionName { get; }

		bool NeedHealth();

		bool NeedDisinfection();

		bool NeedWeaponAmmo();

		bool NeedToolAmmo();

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

		void GiveHealth(float health);

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

		AIG_CourseNode SpawnNode { get; }

		string PublicName { get; }

		Transform transform { get; }

		bool ObjectiveItemSolved { get; }

		ePickupItemStatus PickupItemStatus { get; }

		PlayerAgent PickedUpByPlayer { get; }

		void ActivateWardenObjectiveItem();

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

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

		public string FullPath { get; set; }

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

		internal const float RETRY_INTERVAL = 0.1f;

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

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

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

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

		private bool m_Allocated = true;

		private float m_ChangedCooldownTimer;

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


		public event LiveEditEventHandler FileChanged;

		public event LiveEditEventHandler FileDeleted;

		public event LiveEditEventHandler FileCreated;

		public event LiveEditEventHandler FileRenamed;

		private LiveEditListener()
		{
		}

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

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

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

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

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

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

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

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

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

		private static T s_CurrentData;

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

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

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


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

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

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

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

		public static bool TryParseVectorString(string input, out float[] vectorArray)
		{
			try
			{
				MatchCollection matchCollection = s_VectorRegex.Matches(input);
				int count = matchCollection.Count;
				if (count < 1)
				{
					throw new Exception();
				}
				vectorArray = new float[count];
				for (int i = 0; i < count; i++)
				{
					Match match = matchCollection[i];
					vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture);
				}
				return true;
			}
			catch
			{
				vectorArray = null;
				return false;
			}
		}
	}
	public static class StringUtils
	{
		private static readonly uint[] _lookup32 = ((Func<uint[]>)delegate
		{
			uint[] array = new uint[256];
			for (int i = 0; i < 256; i++)
			{
				string text = i.ToString("X2");
				if (BitConverter.IsLittleEndian)
				{
					array[i] = text[0] + ((uint)text[1] << 16);
				}
				else
				{
					array[i] = text[1] + ((uint)text[0] << 16);
				}
			}
			return array;
		})();

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

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

		private readonly List<Coroutine> m_InLevelCoroutines;

		private static CoroutineDispatcher_Impl s_Instance;

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

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

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

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

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

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

		private static ThreadDispatcher_Impl s_Instance;

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

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

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

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

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

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

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

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


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


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


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


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


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


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


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


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


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

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

		public const byte MagicSize = 9;

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

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

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

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

			public string Name;

			public string Version;

			public string Checksum;
		}

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

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

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

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

		private static bool m_PatchApplied;

		private static INativeDetour s_ReadFromDiskDetour;

		private static ReadFromDiskDelegate s_ReadFromDiskOriginal;

		private static INativeDetour s_SaveToDiskDetour;

		private static SaveToDiskDelegate s_SaveToDiskOriginal;

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

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

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

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

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

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

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

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

		public override string JmpStartMask => "xxxxxxxxxxxxxxx";

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

		public override uint TrampolineSize => 13u;

		public unsafe override SyringeUsedDelegate To => OnSyringeApplyEffect;

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

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

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

plugins/GTFO8PlayerREACTORPlugin.dll

Decompiled 3 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Agents;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GTFO.API;
using Il2CppSystem.Collections.Generic;
using Player;
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("GTFO8PlayerREACTORPlugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GTFO8PlayerREACTORPlugin")]
[assembly: AssemblyTitle("GTFO8PlayerREACTORPlugin")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GTFO8PlayerREACTORPlugin;

internal class MaxAmmoMono : MonoBehaviour
{
	public static void GiveAmmo()
	{
		Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
		while (enumerator.MoveNext())
		{
			PlayerBackpackManager.GiveAmmoToPlayer(((Agent)enumerator.Current).m_replicator.OwningPlayer, 1f, 1f, 1f);
		}
	}
}
[BepInPlugin("GTFO8PlayerREACTORPlugin", "GTFO8PlayerREACTORPlugin", "1.0.0")]
public class Plugin : BasePlugin
{
	public override void Load()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		ManualLogSource log = ((BasePlugin)this).Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 0, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GTFO8PlayerREACTORPlugin is loaded!");
		}
		log.LogInfo(val);
		LevelAPI.OnEnterLevel += MaxAmmoMono.GiveAmmo;
	}
}