Decompiled source of cortador de unha v1.0.0

mods/2018-LC_API-3.4.5/BepInEx/plugins/LC_API.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.BundleAPI;
using LC_API.ClientAPI;
using LC_API.Comp;
using LC_API.Data;
using LC_API.Exceptions;
using LC_API.Extensions;
using LC_API.GameInterfaceAPI;
using LC_API.GameInterfaceAPI.Events;
using LC_API.GameInterfaceAPI.Events.Cache;
using LC_API.GameInterfaceAPI.Events.EventArgs.Player;
using LC_API.GameInterfaceAPI.Events.Handlers;
using LC_API.GameInterfaceAPI.Features;
using LC_API.ManualPatches;
using LC_API.Networking;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Steamworks;
using Steamworks.Data;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("2018")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Utilities for plugin devs")]
[assembly: AssemblyFileVersion("3.4.5.0")]
[assembly: AssemblyInformationalVersion("3.4.5+ae2de74676f4f0d6440c82067f4c1a22389fe27b")]
[assembly: AssemblyProduct("Lethal Company API")]
[assembly: AssemblyTitle("LC_API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LC_API
{
	internal static class CheatDatabase
	{
		private const string SIG_REQ_GUID = "LC_API_ReqGUID";

		private const string SIG_SEND_MODS = "LC_APISendMods";

		private static Dictionary<string, PluginInfo> PluginsLoaded = new Dictionary<string, PluginInfo>();

		public static void RunLocalCheatDetector()
		{
			PluginsLoaded = Chainloader.PluginInfos;
			using Dictionary<string, PluginInfo>.ValueCollection.Enumerator enumerator = PluginsLoaded.Values.GetEnumerator();
			while (enumerator.MoveNext())
			{
				switch (enumerator.Current.Metadata.GUID)
				{
				case "mikes.lethalcompany.mikestweaks":
				case "mom.llama.enhancer":
				case "Posiedon.GameMaster":
				case "LethalCompanyScalingMaster":
				case "verity.amberalert":
					ModdedServer.SetServerModdedOnly();
					break;
				}
			}
		}

		public static void OtherPlayerCheatDetector()
		{
			Plugin.Log.LogWarning((object)"Asking all other players for their mod list..");
			LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.QueueTip("Mod List:", "Asking all other players for installed mods..");
			LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.QueueTip("Mod List:", "Check the logs for more detailed results.\n<size=13>(Note that if someone doesnt show up on the list, they may not have LC_API installed)</size>");
			Network.Broadcast("LC_API_ReqGUID");
		}

		[NetworkMessage("LC_APISendMods", false)]
		internal static void ReceivedModListHandler(ulong senderId, List<string> mods)
		{
			string text = LC_API.GameInterfaceAPI.Features.Player.Get(senderId).Username + " responded with these mods:\n" + string.Join("\n", mods);
			LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.QueueTip("Mod List:", text);
			Plugin.Log.LogWarning((object)text);
		}

		[NetworkMessage("LC_API_ReqGUID", false)]
		internal static void ReceivedModListHandler(ulong senderId)
		{
			List<string> list = new List<string>();
			foreach (PluginInfo value in PluginsLoaded.Values)
			{
				list.Add(value.Metadata.GUID);
			}
			Network.Broadcast("LC_APISendMods", list);
		}
	}
	[BepInPlugin("LC_API", "Lethal Company API", "3.4.5")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private ConfigEntry<bool> configOverrideModServer;

		private ConfigEntry<bool> configLegacyAssetLoading;

		private ConfigEntry<bool> configDisableBundleLoader;

		internal static ConfigEntry<bool> configVanillaSupport;

		internal static Harmony Harmony;

		internal static Plugin Instance { get; private set; }

		public static bool Initialized { get; private set; }

		private void Awake()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Expected O, but got Unknown
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Expected O, but got Unknown
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Expected O, but got Unknown
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Expected O, but got Unknown
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Expected O, but got Unknown
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Expected O, but got Unknown
			Instance = this;
			configOverrideModServer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force modded server browser", false, "Should the API force you into the modded server browser?");
			configLegacyAssetLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Legacy asset bundle loading", false, "Should the BundleLoader use legacy asset loading? Turning this on may help with loading assets from older plugins.");
			configDisableBundleLoader = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Disable BundleLoader", false, "Should the BundleLoader be turned off? Enable this if you are having problems with mods that load assets using a different method from LC_API's BundleLoader.");
			configVanillaSupport = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "Vanilla Compatibility", false, "Allows you to join vanilla servers, but disables many networking-related things and could cause mods to not work properly.");
			CommandHandler.commandPrefix = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Prefix", "/", "Command prefix");
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogWarning((object)"\n.____    _________           _____  __________ .___  \r\n|    |   \\_   ___ \\         /  _  \\ \\______   \\|   | \r\n|    |   /    \\  \\/        /  /_\\  \\ |     ___/|   | \r\n|    |___\\     \\____      /    |    \\|    |    |   | \r\n|_______ \\\\______  /______\\____|__  /|____|    |___| \r\n        \\/       \\//_____/        \\/                 \r\n                                                     ");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Starting up..");
			if (configOverrideModServer.Value)
			{
				ModdedServer.SetServerModdedOnly();
			}
			if (configVanillaSupport.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API is starting with VANILLA SUPPORT ENABLED.");
			}
			Harmony = new Harmony("ModAPI");
			MethodInfo methodInfo = AccessTools.Method(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated", (Type[])null, (Type[])null);
			AccessTools.Method(typeof(GameNetworkManager), "LobbyDataIsJoinable", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ServerPatch), "OnLobbyCreate", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(MenuManager), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(ServerPatch), "CacheMenuManager", (Type[])null, (Type[])null);
			AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(HUDManager), "SubmitChat_performed", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(CommandHandler.SubmitChatPatch), "Transpiler", (Type[])null, (Type[])null);
			MethodInfo methodInfo7 = AccessTools.Method(typeof(GameNetworkManager), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo8 = AccessTools.Method(typeof(ServerPatch), "GameNetworkManagerAwake", (Type[])null, (Type[])null);
			MethodInfo methodInfo9 = AccessTools.Method(typeof(NetworkManager), "StartClient", (Type[])null, (Type[])null);
			MethodInfo methodInfo10 = AccessTools.Method(typeof(NetworkManager), "StartHost", (Type[])null, (Type[])null);
			MethodInfo methodInfo11 = AccessTools.Method(typeof(NetworkManager), "Shutdown", (Type[])null, (Type[])null);
			MethodInfo methodInfo12 = AccessTools.Method(typeof(RegisterPatch), "Postfix", (Type[])null, (Type[])null);
			MethodInfo methodInfo13 = AccessTools.Method(typeof(UnregisterPatch), "Postfix", (Type[])null, (Type[])null);
			Harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo9, (HarmonyMethod)null, new HarmonyMethod(methodInfo12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo10, (HarmonyMethod)null, new HarmonyMethod(methodInfo12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo11, (HarmonyMethod)null, new HarmonyMethod(methodInfo13), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Network.Init();
			Events.Patch(Harmony);
		}

		internal void Start()
		{
			Initialize();
		}

		internal void OnDestroy()
		{
			Initialize();
		}

		internal void Initialize()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!Initialized)
			{
				Initialized = true;
				if (!configDisableBundleLoader.Value)
				{
					BundleLoader.Load(configLegacyAssetLoading.Value);
				}
				GameObject val = new GameObject("API");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<LC_APIManager>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Started!");
				CheatDatabase.RunLocalCheatDetector();
			}
		}

		internal static void PatchMethodManual(MethodInfo method, MethodInfo patch, Harmony harmony)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			harmony.Patch((MethodBase)method, new HarmonyMethod(patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	public static class Utils
	{
		public static string ReplaceWithCase(this string input, string toReplace, string replacement)
		{
			Dictionary<string, string> map = new Dictionary<string, string> { { toReplace, replacement } };
			return input.ReplaceWithCase(map);
		}

		public static string ReplaceWithCase(this string input, Dictionary<string, string> map)
		{
			string text = input;
			foreach (KeyValuePair<string, string> item in map)
			{
				string key = item.Key;
				string value = item.Value;
				text = Regex.Replace(text, key, delegate(Match match)
				{
					string value2 = match.Value;
					char[] array = value2.ToCharArray();
					string[] source = value2.Split(' ');
					bool flag = char.IsUpper(array[0]);
					bool flag2 = source.All((string w) => char.IsUpper(w[0]) || !char.IsLetter(w[0]));
					if (array.All((char c) => char.IsUpper(c) || !char.IsLetter(c)))
					{
						return value.ToUpper();
					}
					if (flag2)
					{
						return Regex.Replace(value, "\\b\\w", (Match charMatch) => charMatch.Value.ToUpper());
					}
					char[] array2 = value.ToCharArray();
					array2[0] = (flag ? char.ToUpper(array2[0]) : char.ToLower(array2[0]));
					return new string(array2);
				}, RegexOptions.IgnoreCase);
			}
			return text;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LC_API";

		public const string PLUGIN_NAME = "Lethal Company API";

		public const string PLUGIN_VERSION = "3.4.5";
	}
}
namespace LC_API.ServerAPI
{
	public static class ModdedServer
	{
		private static bool moddedOnly;

		[Obsolete("Use SetServerModdedOnly() instead. This will be removed/private in a future update.")]
		public static bool setModdedOnly;

		public static int GameVersion { get; internal set; }

		public static bool ModdedOnly => moddedOnly;

		public static void SetServerModdedOnly()
		{
			moddedOnly = true;
			Plugin.Log.LogMessage((object)"A plugin has set your game to only allow you to play with other people who have mods!");
		}

		public static void OnSceneLoaded()
		{
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && ModdedOnly)
			{
				GameNetworkManager instance = GameNetworkManager.Instance;
				instance.gameVersionNum += 16440;
				setModdedOnly = true;
			}
		}
	}
	[Obsolete("ServerAPI.Networking is obsolete and will be removed in future versions. Use LC_API.Networking.Network.")]
	public static class Networking
	{
		private sealed class Data<T>
		{
			public readonly string Signature;

			public readonly T Value;

			public Data(string signature, T value)
			{
				Signature = signature;
				Value = value;
			}
		}

		private const string StringMessageRegistrationName = "LCAPI_NET_LEGACY_STRING";

		private const string ListStringMessageRegistrationName = "LCAPI_NET_LEGACY_LISTSTRING";

		private const string IntMessageRegistrationName = "LCAPI_NET_LEGACY_INT";

		private const string FloatMessageRegistrationName = "LCAPI_NET_LEGACY_FLOAT";

		private const string Vector3MessageRegistrationName = "LCAPI_NET_LEGACY_VECTOR3";

		private const string SyncVarMessageRegistrationName = "LCAPI_NET_LEGACY_SYNCVAR_SET";

		public static Action<string, string> GetString = delegate
		{
		};

		public static Action<List<string>, string> GetListString = delegate
		{
		};

		public static Action<int, string> GetInt = delegate
		{
		};

		public static Action<float, string> GetFloat = delegate
		{
		};

		public static Action<Vector3, string> GetVector3 = delegate
		{
		};

		private static Dictionary<string, string> syncStringVars = new Dictionary<string, string>();

		public static void Broadcast(string data, string signature)
		{
			if (data.Contains("/"))
			{
				Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
			}
			else
			{
				Network.Broadcast("LCAPI_NET_LEGACY_STRING", new Data<string>(signature, data));
			}
		}

		public static void Broadcast(List<string> data, string signature)
		{
			string text = "";
			foreach (string datum in data)
			{
				if (datum.Contains("/"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
					return;
				}
				if (datum.Contains("\n"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( NewLine )");
					return;
				}
				text = text + datum + "\n";
			}
			Network.Broadcast("LCAPI_NET_LEGACY_LISTSTRING", new Data<string>(signature, text));
		}

		public static void Broadcast(int data, string signature)
		{
			Network.Broadcast("LCAPI_NET_LEGACY_INT", new Data<int>(signature, data));
		}

		public static void Broadcast(float data, string signature)
		{
			Network.Broadcast("LCAPI_NET_LEGACY_FLOAT", new Data<float>(signature, data));
		}

		public static void Broadcast(Vector3 data, string signature)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Network.Broadcast("LCAPI_NET_LEGACY_VECTOR3", new Data<Vector3>(signature, data));
		}

		public static void RegisterSyncVariable(string name)
		{
			if (!syncStringVars.ContainsKey(name))
			{
				syncStringVars.Add(name, "");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot register Sync Variable! A Sync Variable has already been registered with name " + name));
			}
		}

		public static void SetSyncVariable(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
				Broadcast(new List<string> { name, value }, "LCAPI_NET_LEGACY_SYNCVAR_SET");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		private static void SetSyncVariableB(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		internal static void LCAPI_NET_SYNCVAR_SET(List<string> list, string arg2)
		{
			if (arg2 == "LCAPI_NET_LEGACY_SYNCVAR_SET")
			{
				SetSyncVariableB(list[0], list[1]);
			}
		}

		public static string GetSyncVariable(string name)
		{
			if (syncStringVars.ContainsKey(name))
			{
				return syncStringVars[name];
			}
			Plugin.Log.LogError((object)("Cannot get the value of Sync Variable " + name + " as it is not registered!"));
			return "";
		}

		internal static void InitializeLegacyNetworking()
		{
			GetListString = (Action<List<string>, string>)Delegate.Combine(GetListString, new Action<List<string>, string>(LCAPI_NET_SYNCVAR_SET));
			Network.RegisterMessage("LCAPI_NET_LEGACY_STRING", relayToSelf: false, delegate(ulong senderId, Data<string> data)
			{
				GetString(data.Value, data.Signature);
			});
			Network.RegisterMessage("LCAPI_NET_LEGACY_LISTSTRING", relayToSelf: false, delegate(ulong senderId, Data<string> data)
			{
				GetListString(data.Value.Split('\n').ToList(), data.Signature);
			});
			Network.RegisterMessage("LCAPI_NET_LEGACY_INT", relayToSelf: false, delegate(ulong senderId, Data<int> data)
			{
				GetInt(data.Value, data.Signature);
			});
			Network.RegisterMessage("LCAPI_NET_LEGACY_FLOAT", relayToSelf: false, delegate(ulong senderId, Data<float> data)
			{
				GetFloat(data.Value, data.Signature);
			});
			Network.RegisterMessage("LCAPI_NET_LEGACY_VECTOR3", relayToSelf: false, delegate(ulong senderId, Data<Vector3> data)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				GetVector3(data.Value, data.Signature);
			});
		}
	}
}
namespace LC_API.Networking
{
	public static class Network
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HandleNamedMessageDelegate <>9__35_2;

			public static Events.CustomEventHandler <>9__35_0;

			public static Events.CustomEventHandler <>9__35_1;

			internal void <Init>b__35_0()
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				StartedNetworking = true;
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
					object obj = <>9__35_2;
					if (obj == null)
					{
						HandleNamedMessageDelegate val = delegate(ulong senderClientId, FastBufferReader reader)
						{
							//IL_0006: Unknown result type (might be due to invalid IL or missing references)
							//IL_000c: Unknown result type (might be due to invalid IL or missing references)
							//IL_003d: Unknown result type (might be due to invalid IL or missing references)
							//IL_0043: Unknown result type (might be due to invalid IL or missing references)
							//IL_0059: Unknown result type (might be due to invalid IL or missing references)
							byte[] bytes = default(byte[]);
							((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
							NetworkMessageWrapper networkMessageWrapper = bytes.ToObject<NetworkMessageWrapper>();
							networkMessageWrapper.Sender = senderClientId;
							byte[] array = networkMessageWrapper.ToBytes();
							FastBufferWriter val2 = default(FastBufferWriter);
							((FastBufferWriter)(ref val2))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
							try
							{
								((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(array, default(ForPrimitives));
								NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(networkMessageWrapper.UniqueName, val2, (NetworkDelivery)4);
							}
							finally
							{
								((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
							}
						};
						<>9__35_2 = val;
						obj = (object)val;
					}
					customMessagingManager.RegisterNamedMessageHandler("LC_API_RELAY_MESSAGE", (HandleNamedMessageDelegate)obj);
				}
				RegisterAllMessages();
			}

			internal void <Init>b__35_2(ulong senderClientId, FastBufferReader reader)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				byte[] bytes = default(byte[]);
				((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
				NetworkMessageWrapper networkMessageWrapper = bytes.ToObject<NetworkMessageWrapper>();
				networkMessageWrapper.Sender = senderClientId;
				byte[] array = networkMessageWrapper.ToBytes();
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<byte>(array, default(ForPrimitives));
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(networkMessageWrapper.UniqueName, val, (NetworkDelivery)4);
				}
				finally
				{
					((IDisposable)(FastBufferWriter)(ref val)).Dispose();
				}
			}

			internal void <Init>b__35_1()
			{
				StartedNetworking = false;
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("LC_API_RELAY_MESSAGE");
				}
				UnregisterAllMessages();
			}
		}

		internal const string MESSAGE_RELAY_UNIQUE_NAME = "LC_API_RELAY_MESSAGE";

		private static MethodInfo _registerInfo = null;

		private static MethodInfo _registerInfoGeneric = null;

		internal static Dictionary<string, NetworkMessageFinalizerBase> NetworkMessageFinalizers { get; } = new Dictionary<string, NetworkMessageFinalizerBase>();


		internal static bool StartedNetworking { get; set; } = false;


		internal static MethodInfo RegisterInfo
		{
			get
			{
				if (_registerInfo == null)
				{
					MethodInfo[] methods = typeof(Network).GetMethods();
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.Name == "RegisterMessage" && !methodInfo.IsGenericMethod)
						{
							_registerInfo = methodInfo;
							break;
						}
					}
				}
				return _registerInfo;
			}
		}

		internal static MethodInfo RegisterInfoGeneric
		{
			get
			{
				if (_registerInfoGeneric == null)
				{
					MethodInfo[] methods = typeof(Network).GetMethods();
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.Name == "RegisterMessage" && methodInfo.IsGenericMethod)
						{
							_registerInfoGeneric = methodInfo;
							break;
						}
					}
				}
				return _registerInfoGeneric;
			}
		}

		public static event Events.CustomEventHandler RegisterNetworkMessages;

		internal static event Events.CustomEventHandler UnregisterNetworkMessages;

		internal static byte[] ToBytes(this object @object)
		{
			if (@object == null)
			{
				return null;
			}
			return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@object));
		}

		internal static T ToObject<T>(this byte[] bytes) where T : class
		{
			return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(bytes));
		}

		internal static void OnRegisterNetworkMessages()
		{
			Network.RegisterNetworkMessages.InvokeSafely();
		}

		internal static void OnUnregisterNetworkMessages()
		{
			Network.UnregisterNetworkMessages.InvokeSafely();
		}

		internal static void RegisterAllMessages()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			foreach (NetworkMessageFinalizerBase value in NetworkMessageFinalizers.Values)
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(value.UniqueName, new HandleNamedMessageDelegate(value.Read));
			}
		}

		internal static void UnregisterAllMessages()
		{
			foreach (string key in NetworkMessageFinalizers.Keys)
			{
				UnregisterMessage(key, andRemoveHandler: false);
			}
		}

		public static void RegisterAll()
		{
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly);
			for (int i = 0; i < typesFromAssembly.Length; i++)
			{
				RegisterAll(typesFromAssembly[i]);
			}
		}

		public static void RegisterAll(Type type)
		{
			if (!type.IsClass)
			{
				return;
			}
			NetworkMessage customAttribute = type.GetCustomAttribute<NetworkMessage>();
			if (customAttribute != null)
			{
				if (type.BaseType.Name == "NetworkMessageHandler`1")
				{
					Type type2 = type.BaseType.GetGenericArguments()[0];
					RegisterInfoGeneric.MakeGenericMethod(type2).Invoke(null, new object[3]
					{
						customAttribute.UniqueName,
						customAttribute.RelayToSelf,
						type.GetMethod("Handler").CreateDelegate(typeof(Action<, >).MakeGenericType(typeof(ulong), type2), Activator.CreateInstance(type))
					});
				}
				else if (type.BaseType.Name == "NetworkMessageHandler")
				{
					RegisterInfo.Invoke(null, new object[3]
					{
						customAttribute.UniqueName,
						customAttribute.RelayToSelf,
						type.GetMethod("Handler").CreateDelegate(typeof(Action<>).MakeGenericType(typeof(ulong)), Activator.CreateInstance(type))
					});
				}
				return;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				customAttribute = methodInfo.GetCustomAttribute<NetworkMessage>();
				if (customAttribute != null)
				{
					if (!methodInfo.IsStatic)
					{
						throw new Exception("Detected NetworkMessage attribute on non-static method. All NetworkMessages on methods must be static.");
					}
					if (methodInfo.GetParameters().Length == 1)
					{
						RegisterInfo.Invoke(null, new object[3]
						{
							customAttribute.UniqueName,
							customAttribute.RelayToSelf,
							methodInfo.CreateDelegate(typeof(Action<>).MakeGenericType(typeof(ulong)))
						});
					}
					else
					{
						Type parameterType = methodInfo.GetParameters()[1].ParameterType;
						RegisterInfoGeneric.MakeGenericMethod(parameterType).Invoke(null, new object[3]
						{
							customAttribute.UniqueName,
							customAttribute.RelayToSelf,
							methodInfo.CreateDelegate(typeof(Action<, >).MakeGenericType(typeof(ulong), parameterType))
						});
					}
				}
			}
		}

		public static void UnregisterAll(bool andRemoveHandler = true)
		{
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly);
			for (int i = 0; i < typesFromAssembly.Length; i++)
			{
				UnregisterAll(typesFromAssembly[i], andRemoveHandler);
			}
		}

		public static void UnregisterAll(Type type, bool andRemoveHandler = true)
		{
			if (!type.IsClass)
			{
				return;
			}
			NetworkMessage customAttribute = type.GetCustomAttribute<NetworkMessage>();
			if (customAttribute != null)
			{
				UnregisterMessage(customAttribute.UniqueName, andRemoveHandler);
				return;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < methods.Length; i++)
			{
				customAttribute = methods[i].GetCustomAttribute<NetworkMessage>();
				if (customAttribute != null)
				{
					UnregisterMessage(customAttribute.UniqueName, andRemoveHandler);
				}
			}
		}

		public static void RegisterMessage<T>(string uniqueName, bool relayToSelf, Action<ulong, T> onReceived) where T : class
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if (NetworkMessageFinalizers.ContainsKey(uniqueName))
			{
				throw new Exception(uniqueName + " already registered");
			}
			NetworkMessageFinalizer<T> networkMessageFinalizer = new NetworkMessageFinalizer<T>(uniqueName, relayToSelf, onReceived);
			NetworkMessageFinalizers.Add(uniqueName, networkMessageFinalizer);
			if (StartedNetworking)
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(uniqueName, new HandleNamedMessageDelegate(networkMessageFinalizer.Read));
			}
		}

		public static void RegisterMessage(string uniqueName, bool relayToSelf, Action<ulong> onReceived)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if (NetworkMessageFinalizers.ContainsKey(uniqueName))
			{
				throw new Exception(uniqueName + " already registered");
			}
			NetworkMessageFinalizer networkMessageFinalizer = new NetworkMessageFinalizer(uniqueName, relayToSelf, onReceived);
			NetworkMessageFinalizers.Add(uniqueName, networkMessageFinalizer);
			if (StartedNetworking)
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(uniqueName, new HandleNamedMessageDelegate(networkMessageFinalizer.Read));
			}
		}

		public static void UnregisterMessage(string uniqueName, bool andRemoveHandler = true)
		{
			if ((!andRemoveHandler && NetworkMessageFinalizers.ContainsKey(uniqueName)) || (andRemoveHandler && NetworkMessageFinalizers.Remove(uniqueName)))
			{
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(uniqueName);
			}
		}

		public static void Broadcast<T>(string uniqueName, T @object) where T : class
		{
			if (NetworkMessageFinalizers.TryGetValue(uniqueName, out var value))
			{
				if (!(value is NetworkMessageFinalizer<T> networkMessageFinalizer))
				{
					throw new Exception("Network handler for " + uniqueName + " was not broadcast with the right type!");
				}
				networkMessageFinalizer.Send(@object);
			}
		}

		public static void Broadcast(string uniqueName)
		{
			if (NetworkMessageFinalizers.TryGetValue(uniqueName, out var value))
			{
				if (!(value is NetworkMessageFinalizer networkMessageFinalizer))
				{
					throw new Exception("Network handler for " + uniqueName + " was not broadcast with the right type!");
				}
				networkMessageFinalizer.Send();
			}
		}

		internal static void Init()
		{
			RegisterNetworkMessages += delegate
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				StartedNetworking = true;
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
					object obj = <>c.<>9__35_2;
					if (obj == null)
					{
						HandleNamedMessageDelegate val = delegate(ulong senderClientId, FastBufferReader reader)
						{
							//IL_0006: Unknown result type (might be due to invalid IL or missing references)
							//IL_000c: Unknown result type (might be due to invalid IL or missing references)
							//IL_003d: Unknown result type (might be due to invalid IL or missing references)
							//IL_0043: Unknown result type (might be due to invalid IL or missing references)
							//IL_0059: Unknown result type (might be due to invalid IL or missing references)
							byte[] bytes = default(byte[]);
							((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
							NetworkMessageWrapper networkMessageWrapper = bytes.ToObject<NetworkMessageWrapper>();
							networkMessageWrapper.Sender = senderClientId;
							byte[] array = networkMessageWrapper.ToBytes();
							FastBufferWriter val2 = default(FastBufferWriter);
							((FastBufferWriter)(ref val2))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
							try
							{
								((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(array, default(ForPrimitives));
								NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(networkMessageWrapper.UniqueName, val2, (NetworkDelivery)4);
							}
							finally
							{
								((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
							}
						};
						<>c.<>9__35_2 = val;
						obj = (object)val;
					}
					customMessagingManager.RegisterNamedMessageHandler("LC_API_RELAY_MESSAGE", (HandleNamedMessageDelegate)obj);
				}
				RegisterAllMessages();
			};
			UnregisterNetworkMessages += delegate
			{
				StartedNetworking = false;
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("LC_API_RELAY_MESSAGE");
				}
				UnregisterAllMessages();
			};
			SetupNetworking();
			RegisterAll();
			LC_API.ServerAPI.Networking.InitializeLegacyNetworking();
		}

		internal static void SetupNetworking()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	public class NetworkMessage : Attribute
	{
		public string UniqueName { get; }

		public bool RelayToSelf { get; }

		public NetworkMessage(string uniqueName, bool relayToSelf = false)
		{
			UniqueName = uniqueName;
			RelayToSelf = relayToSelf;
		}
	}
	public abstract class NetworkMessageHandler<T> where T : class
	{
		public abstract void Handler(ulong sender, T message);
	}
	public abstract class NetworkMessageHandler
	{
		public abstract void Handler(ulong sender);
	}
	internal abstract class NetworkMessageFinalizerBase
	{
		internal abstract string UniqueName { get; }

		internal abstract bool RelayToSelf { get; }

		public abstract void Read(ulong sender, FastBufferReader reader);
	}
	internal class NetworkMessageFinalizer : NetworkMessageFinalizerBase
	{
		internal override string UniqueName { get; }

		internal override bool RelayToSelf { get; }

		internal Action<ulong> OnReceived { get; }

		public NetworkMessageFinalizer(string uniqueName, bool relayToSelf, Action<ulong> onReceived)
		{
			UniqueName = uniqueName;
			RelayToSelf = relayToSelf;
			OnReceived = onReceived;
		}

		public void Send()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(SendLater());
				return;
			}
			byte[] array = new NetworkMessageWrapper(UniqueName, LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.ClientId).ToBytes();
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(array, default(ForPrimitives));
				if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(UniqueName, val, (NetworkDelivery)4);
				}
				else
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LC_API_RELAY_MESSAGE", LC_API.GameInterfaceAPI.Features.Player.HostPlayer.ClientId, val, (NetworkDelivery)4);
				}
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public override void Read(ulong fakeSender, FastBufferReader reader)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(ReadLater(fakeSender, reader));
				return;
			}
			byte[] bytes = default(byte[]);
			((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
			NetworkMessageWrapper networkMessageWrapper = bytes.ToObject<NetworkMessageWrapper>();
			if (RelayToSelf || LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.ClientId != networkMessageWrapper.Sender)
			{
				OnReceived(networkMessageWrapper.Sender);
			}
		}

		private IEnumerator SendLater()
		{
			int timesWaited = 0;
			while ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.1f);
				timesWaited++;
				if (timesWaited % 20 == 0)
				{
					Plugin.Log.LogWarning((object)$"Waiting to send network message. Waiting on host?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null} Waiting on local player?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null}");
				}
				if (timesWaited >= 100)
				{
					Plugin.Log.LogError((object)"Dropping network message");
					yield return null;
				}
			}
			Send();
		}

		private IEnumerator ReadLater(ulong fakeSender, FastBufferReader reader)
		{
			//IL_0015: 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)
			int timesWaited = 0;
			while ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.1f);
				timesWaited++;
				if (timesWaited % 20 == 0)
				{
					Plugin.Log.LogWarning((object)$"Waiting to read network message. Waiting on host?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null} Waiting on local player?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null}");
				}
				if (timesWaited >= 100)
				{
					Plugin.Log.LogError((object)"Dropping network message");
					yield return null;
				}
			}
			Read(fakeSender, reader);
		}
	}
	internal class NetworkMessageFinalizer<T> : NetworkMessageFinalizerBase where T : class
	{
		internal override string UniqueName { get; }

		internal override bool RelayToSelf { get; }

		internal Action<ulong, T> OnReceived { get; }

		public NetworkMessageFinalizer(string uniqueName, bool relayToSelf, Action<ulong, T> onReceived)
		{
			UniqueName = uniqueName;
			RelayToSelf = relayToSelf;
			OnReceived = onReceived;
		}

		public void Send(T obj)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(SendLater(obj));
				return;
			}
			byte[] array = new NetworkMessageWrapper(UniqueName, LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.ClientId, obj.ToBytes()).ToBytes();
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(FastBufferWriter.GetWriteSize<byte>(array, -1, 0), (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(array, default(ForPrimitives));
				if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(UniqueName, val, (NetworkDelivery)4);
				}
				else
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LC_API_RELAY_MESSAGE", LC_API.GameInterfaceAPI.Features.Player.HostPlayer.ClientId, val, (NetworkDelivery)4);
				}
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public override void Read(ulong fakeSender, FastBufferReader reader)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(ReadLater(fakeSender, reader));
				return;
			}
			byte[] bytes = default(byte[]);
			((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref bytes, default(ForPrimitives));
			NetworkMessageWrapper networkMessageWrapper = bytes.ToObject<NetworkMessageWrapper>();
			if (RelayToSelf || LC_API.GameInterfaceAPI.Features.Player.LocalPlayer.ClientId != networkMessageWrapper.Sender)
			{
				OnReceived(networkMessageWrapper.Sender, networkMessageWrapper.Message.ToObject<T>());
			}
		}

		private IEnumerator SendLater(T obj)
		{
			int timesWaited = 0;
			while ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.1f);
				timesWaited++;
				if (timesWaited % 20 == 0)
				{
					Plugin.Log.LogWarning((object)$"Waiting to send network message. Waiting on host?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null} Waiting on local player?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null}");
				}
				if (timesWaited >= 100)
				{
					Plugin.Log.LogError((object)"Dropping network message");
					yield return null;
				}
			}
			Send(obj);
		}

		private IEnumerator ReadLater(ulong fakeSender, FastBufferReader reader)
		{
			//IL_0015: 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)
			int timesWaited = 0;
			while ((Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null || (Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.1f);
				timesWaited++;
				if (timesWaited % 20 == 0)
				{
					Plugin.Log.LogWarning((object)$"Waiting to read network message. Waiting on host?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.HostPlayer == (Object)null} Waiting on local player?: {(Object)(object)LC_API.GameInterfaceAPI.Features.Player.LocalPlayer == (Object)null}");
				}
				if (timesWaited >= 100)
				{
					Plugin.Log.LogError((object)"Dropping network message");
					yield return null;
				}
			}
			Read(fakeSender, reader);
		}
	}
	internal class NetworkMessageWrapper
	{
		public string UniqueName { get; set; }

		public ulong Sender { get; set; }

		public byte[] Message { get; set; }

		internal NetworkMessageWrapper(string uniqueName, ulong sender)
		{
			UniqueName = uniqueName;
			Sender = sender;
		}

		internal NetworkMessageWrapper(string uniqueName, ulong sender, byte[] message)
		{
			UniqueName = uniqueName;
			Sender = sender;
			Message = message;
		}

		internal NetworkMessageWrapper()
		{
		}
	}
	internal static class RegisterPatch
	{
		internal static void Postfix()
		{
			Network.OnRegisterNetworkMessages();
		}
	}
	internal static class UnregisterPatch
	{
		internal static void Postfix()
		{
			Network.OnUnregisterNetworkMessages();
		}
	}
}
namespace LC_API.Networking.Serializers
{
	public struct Vector2S
	{
		private Vector2? v2;

		public float x { get; set; }

		public float y { get; set; }

		[JsonIgnore]
		public Vector2 vector2
		{
			get
			{
				//IL_002f: 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)
				if (!v2.HasValue)
				{
					v2 = new Vector2(x, y);
				}
				return v2.Value;
			}
		}

		public Vector2S(float x, float y)
		{
			v2 = null;
			this.x = x;
			this.y = y;
		}

		public static implicit operator Vector2(Vector2S vector2S)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return vector2S.vector2;
		}

		public static implicit operator Vector2S(Vector2 vector2)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2S(vector2.x, vector2.y);
		}
	}
	public struct Vector2IntS
	{
		private Vector2Int? v2;

		public int x { get; set; }

		public int y { get; set; }

		[JsonIgnore]
		public Vector2Int vector2
		{
			get
			{
				//IL_002f: 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)
				if (!v2.HasValue)
				{
					v2 = new Vector2Int(x, y);
				}
				return v2.Value;
			}
		}

		public Vector2IntS(int x, int y)
		{
			v2 = null;
			this.x = x;
			this.y = y;
		}

		public static implicit operator Vector2Int(Vector2IntS vector2S)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return vector2S.vector2;
		}

		public static implicit operator Vector2IntS(Vector2Int vector2)
		{
			return new Vector2IntS(((Vector2Int)(ref vector2)).x, ((Vector2Int)(ref vector2)).y);
		}
	}
	public struct Vector3S
	{
		private Vector3? v3;

		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

		[JsonIgnore]
		public Vector3 vector3
		{
			get
			{
				//IL_0035: 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 (!v3.HasValue)
				{
					v3 = new Vector3(x, y, z);
				}
				return v3.Value;
			}
		}

		public Vector3S(float x, float y, float z)
		{
			v3 = null;
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public static implicit operator Vector3(Vector3S vector3S)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return vector3S.vector3;
		}

		public static implicit operator Vector3S(Vector3 vector3)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3S(vector3.x, vector3.y, vector3.z);
		}
	}
	public struct Vector3IntS
	{
		private Vector3Int? v3;

		public int x { get; set; }

		public int y { get; set; }

		public int z { get; set; }

		[JsonIgnore]
		public Vector3Int vector3
		{
			get
			{
				//IL_0035: 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 (!v3.HasValue)
				{
					v3 = new Vector3Int(x, y, z);
				}
				return v3.Value;
			}
		}

		public Vector3IntS(int x, int y, int z)
		{
			v3 = null;
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public static implicit operator Vector3Int(Vector3IntS vector3S)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return vector3S.vector3;
		}

		public static implicit operator Vector3IntS(Vector3Int vector3)
		{
			return new Vector3IntS(((Vector3Int)(ref vector3)).x, ((Vector3Int)(ref vector3)).y, ((Vector3Int)(ref vector3)).z);
		}
	}
	public struct Vector4S
	{
		private Vector4? v4;

		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

		public float w { get; set; }

		[JsonIgnore]
		public Vector4 Vector4
		{
			get
			{
				//IL_003b: 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)
				if (!v4.HasValue)
				{
					v4 = new Vector4(x, y, z, w);
				}
				return v4.Value;
			}
		}

		public Vector4S(float x, float y, float z, float w)
		{
			v4 = null;
			this.x = x;
			this.y = y;
			this.z = z;
			this.w = w;
		}

		public static implicit operator Vector4(Vector4S vector4S)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return vector4S.Vector4;
		}

		public static implicit operator Vector4S(Vector4 vector4)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector4S(vector4.x, vector4.y, vector4.z, vector4.w);
		}
	}
	public struct QuaternionS
	{
		private Quaternion? q;

		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

		public float w { get; set; }

		[JsonIgnore]
		public Quaternion Quaternion
		{
			get
			{
				//IL_003b: 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)
				if (!q.HasValue)
				{
					q = new Quaternion(x, y, z, w);
				}
				return q.Value;
			}
		}

		public QuaternionS(float x, float y, float z, float w)
		{
			q = null;
			this.x = x;
			this.y = y;
			this.z = z;
			this.w = w;
		}

		public static implicit operator Quaternion(QuaternionS quaternionS)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return quaternionS.Quaternion;
		}

		public static implicit operator QuaternionS(Quaternion quaternion)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new QuaternionS(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
		}
	}
	public struct ColorS
	{
		private Color? c;

		public float r { get; set; }

		public float g { get; set; }

		public float b { get; set; }

		public float a { get; set; }

		[JsonIgnore]
		public Color Color
		{
			get
			{
				//IL_003b: 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)
				if (!c.HasValue)
				{
					c = new Color(r, g, b, a);
				}
				return c.Value;
			}
		}

		public ColorS(float r, float g, float b, float a)
		{
			c = null;
			this.r = r;
			this.g = g;
			this.b = b;
			this.a = a;
		}

		public static implicit operator Color(ColorS colorS)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return colorS.Color;
		}

		public static implicit operator ColorS(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new ColorS(color.r, color.g, color.b, color.a);
		}
	}
	public struct Color32S
	{
		private Color32? c;

		public byte r { get; set; }

		public byte g { get; set; }

		public byte b { get; set; }

		public byte a { get; set; }

		[JsonIgnore]
		public Color32 Color
		{
			get
			{
				//IL_003b: 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)
				if (!c.HasValue)
				{
					c = new Color32(r, g, b, a);
				}
				return c.Value;
			}
		}

		public Color32S(byte r, byte g, byte b, byte a)
		{
			c = null;
			this.r = r;
			this.g = g;
			this.b = b;
			this.a = a;
		}

		public static implicit operator Color32(Color32S colorS)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return colorS.Color;
		}

		public static implicit operator Color32S(Color32 color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Color32S(color.r, color.g, color.b, color.a);
		}
	}
	public struct RayS
	{
		private Ray? r;

		public Vector3S origin { get; set; }

		public Vector3S direction { get; set; }

		[JsonIgnore]
		public Ray Ray
		{
			get
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: 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_0024: Unknown result type (might be due to invalid IL or missing references)
				if (!r.HasValue)
				{
					r = new Ray((Vector3)origin, (Vector3)direction);
				}
				return r.Value;
			}
		}

		public RayS(Vector3 origin, Vector3 direction)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			r = null;
			this.origin = origin;
			this.direction = direction;
		}

		public static implicit operator Ray(RayS rayS)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return rayS.Ray;
		}

		public static implicit operator RayS(Ray ray)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return new RayS(((Ray)(ref ray)).origin, ((Ray)(ref ray)).direction);
		}
	}
	public struct Ray2DS
	{
		private Ray2D? r;

		public Vector2S origin { get; set; }

		public Vector2S direction { get; set; }

		[JsonIgnore]
		public Ray2D Ray
		{
			get
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: 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_0024: Unknown result type (might be due to invalid IL or missing references)
				if (!r.HasValue)
				{
					r = new Ray2D((Vector2)origin, (Vector2)direction);
				}
				return r.Value;
			}
		}

		public Ray2DS(Vector2 origin, Vector2 direction)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			r = null;
			this.origin = origin;
			this.direction = direction;
		}

		public static implicit operator Ray2D(Ray2DS ray2DS)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ray2DS.Ray;
		}

		public static implicit operator Ray2DS(Ray2D ray2D)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return new Ray2DS(((Ray2D)(ref ray2D)).origin, ((Ray2D)(ref ray2D)).direction);
		}
	}
}
namespace LC_API.ManualPatches
{
	internal static class ServerPatch
	{
		internal static bool OnLobbyCreate(GameNetworkManager __instance, Result result, Lobby lobby)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)result != 1)
			{
				Debug.LogError((object)$"Lobby could not be created! {result}", (Object)(object)__instance);
			}
			__instance.lobbyHostSettings.lobbyName = "[MODDED]" + __instance.lobbyHostSettings.lobbyName.ToString();
			Plugin.Log.LogMessage((object)"server pre-setup success");
			return true;
		}

		internal static bool CacheMenuManager(MenuManager __instance)
		{
			LC_APIManager.MenuManager = __instance;
			return true;
		}

		internal static bool ChatCommands(HUDManager __instance, CallbackContext context)
		{
			if (__instance.chatTextField.text.ToLower().Contains("/modcheck"))
			{
				CheatDatabase.OtherPlayerCheatDetector();
				return false;
			}
			return true;
		}

		internal static void GameNetworkManagerAwake(GameNetworkManager __instance)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				ModdedServer.GameVersion = __instance.gameVersionNum;
			}
		}
	}
}
namespace LC_API.GameInterfaceAPI
{
	public static class GameState
	{
		private static readonly Action NothingAction = delegate
		{
		};

		public static int AlivePlayerCount { get; private set; }

		public static ShipState ShipState { get; private set; }

		public static event Action PlayerDied;

		public static event Action LandOnMoon;

		public static event Action WentIntoOrbit;

		public static event Action ShipStartedLeaving;

		internal static void GSUpdate()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (StartOfRound.Instance.shipHasLanded && ShipState != ShipState.OnMoon)
				{
					ShipState = ShipState.OnMoon;
					GameState.LandOnMoon.InvokeActionSafe();
				}
				if (StartOfRound.Instance.inShipPhase && ShipState != 0)
				{
					ShipState = ShipState.InOrbit;
					GameState.WentIntoOrbit.InvokeActionSafe();
				}
				if (StartOfRound.Instance.shipIsLeaving && ShipState != ShipState.LeavingMoon)
				{
					ShipState = ShipState.LeavingMoon;
					GameState.ShipStartedLeaving.InvokeActionSafe();
				}
				if (AlivePlayerCount < StartOfRound.Instance.livingPlayers)
				{
					GameState.PlayerDied.InvokeActionSafe();
				}
				AlivePlayerCount = StartOfRound.Instance.livingPlayers;
			}
		}

		static GameState()
		{
			GameState.PlayerDied = NothingAction;
			GameState.LandOnMoon = NothingAction;
			GameState.WentIntoOrbit = NothingAction;
			GameState.ShipStartedLeaving = NothingAction;
		}
	}
	[Obsolete("Use Player::QueueTip instead.")]
	public class GameTips
	{
		private static List<string> tipHeaders = new List<string>();

		private static List<string> tipBodys = new List<string>();

		private static float lastMessageTime;

		public static void ShowTip(string header, string body)
		{
			tipHeaders.Add(header);
			tipBodys.Add(body);
		}

		public static void UpdateInternal()
		{
			lastMessageTime -= Time.deltaTime;
			if ((tipHeaders.Count > 0) & (lastMessageTime < 0f))
			{
				lastMessageTime = 5f;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.DisplayTip(tipHeaders[0], tipBodys[0], false, false, "LC_Tip1");
				}
				tipHeaders.RemoveAt(0);
				tipBodys.RemoveAt(0);
			}
		}
	}
}
namespace LC_API.GameInterfaceAPI.Features
{
	public class Item : NetworkBehaviour
	{
		private bool hasNewProps;

		internal static GameObject ItemNetworkPrefab { get; set; }

		public static Dictionary<GrabbableObject, Item> Dictionary { get; } = new Dictionary<GrabbableObject, Item>();


		public static IReadOnlyCollection<Item> List => Dictionary.Values;

		public GrabbableObject GrabbableObject { get; private set; }

		public Item ItemProperties => GrabbableObject.itemProperties;

		public ScanNodeProperties ScanNodeProperties { get; set; }

		public bool IsHeld => GrabbableObject.isHeld;

		public bool IsTwoHanded => ItemProperties.twoHanded;

		public Player Holder
		{
			get
			{
				if (!IsHeld)
				{
					return null;
				}
				if (!Player.Dictionary.TryGetValue(GrabbableObject.playerHeldBy, out var value))
				{
					return null;
				}
				return value;
			}
		}

		public string Name
		{
			get
			{
				return ItemProperties.itemName;
			}
			set
			{
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to set item name on client.");
				}
				string oldName = ItemProperties.itemName.ToLower();
				CloneProperties();
				ItemProperties.itemName = value;
				OverrideTooltips(oldName, value.ToLower());
				ScanNodeProperties.headerText = value;
				SetGrabbableNameClientRpc(value);
			}
		}

		public Vector3 Position
		{
			get
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return ((Component)GrabbableObject).transform.position;
			}
			set
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to set item position on client.");
				}
				GrabbableObject.startFallingPosition = value;
				GrabbableObject.targetFloorPosition = value;
				((Component)GrabbableObject).transform.position = value;
				SetItemPositionClientRpc(value);
			}
		}

		public Quaternion Rotation
		{
			get
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return ((Component)GrabbableObject).transform.rotation;
			}
			set
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				((Component)GrabbableObject).transform.rotation = value;
			}
		}

		public Vector3 Scale
		{
			get
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return ((Component)GrabbableObject).transform.localScale;
			}
			set
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				((Component)GrabbableObject).transform.localScale = value;
			}
		}

		public bool IsScrap
		{
			get
			{
				return ItemProperties.isScrap;
			}
			set
			{
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to set item name on client.");
				}
				CloneProperties();
				ItemProperties.isScrap = value;
				SetIsScrapClientRpc(value);
			}
		}

		public int ScrapValue
		{
			get
			{
				return GrabbableObject.scrapValue;
			}
			set
			{
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to set scrap value on client.");
				}
				GrabbableObject.SetScrapValue(value);
				SetScrapValueClientRpc(value);
			}
		}

		[ClientRpc]
		private void SetGrabbableNameClientRpc(string name)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(66243798u, val, (RpcDelivery)0);
				bool flag = name != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(name, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 66243798u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				string oldName = ItemProperties.itemName.ToLower();
				CloneProperties();
				ItemProperties.itemName = name;
				OverrideTooltips(oldName, name.ToLower());
				ScanNodeProperties.headerText = name;
			}
		}

		private void OverrideTooltips(string oldName, string newName)
		{
			for (int i = 0; i < ItemProperties.toolTips.Length; i++)
			{
				ItemProperties.toolTips[i] = ItemProperties.toolTips[i].ReplaceWithCase(oldName, newName);
			}
			if (IsHeld && (Object)(object)Holder == (Object)(object)Player.LocalPlayer)
			{
				GrabbableObject.SetControlTipsForItem();
			}
		}

		[ClientRpc]
		private void SetItemPositionClientRpc(Vector3 pos)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(949135576u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref pos);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 949135576u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					GrabbableObject.startFallingPosition = pos;
					GrabbableObject.targetFloorPosition = pos;
					((Component)GrabbableObject).transform.position = pos;
				}
			}
		}

		public void SetAndSyncRotation(Quaternion rotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to sync item rotation from client.");
			}
			SetItemRotationClientRpc(rotation);
		}

		[ClientRpc]
		private void SetItemRotationClientRpc(Quaternion rotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1528367091u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref rotation);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1528367091u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Rotation = rotation;
				}
			}
		}

		public void SetAndSyncScale(Vector3 scale)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to sync item scale from client.");
			}
			SetItemScaleClientRpc(scale);
		}

		[ClientRpc]
		private void SetItemScaleClientRpc(Vector3 scale)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2688253945u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref scale);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2688253945u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Scale = scale;
				}
			}
		}

		[ClientRpc]
		private void SetIsScrapClientRpc(bool isScrap)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4227417717u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isScrap, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4227417717u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					CloneProperties();
					ItemProperties.isScrap = isScrap;
				}
			}
		}

		[ClientRpc]
		private void SetScrapValueClientRpc(int scrapValue)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3866863385u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, scrapValue);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3866863385u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					GrabbableObject.SetScrapValue(scrapValue);
				}
			}
		}

		public void RemoveFromHolder(Vector3 position = default(Vector3), Quaternion rotation = default(Quaternion))
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to remove item from player on client.");
			}
			if (IsHeld)
			{
				((NetworkBehaviour)this).NetworkObject.RemoveOwnership();
				Holder.Inventory.RemoveItem(this);
				RemoveFromHolderClientRpc();
				Position = position;
				Rotation = rotation;
			}
		}

		[ClientRpc]
		private void RemoveFromHolderClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1050513218u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1050513218u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && IsHeld)
				{
					Holder.Inventory.RemoveItem(this);
				}
			}
		}

		public void EnablePhysics(bool enable)
		{
			GrabbableObject.EnablePhysics(enable);
		}

		public void EnableMeshes(bool enable)
		{
			GrabbableObject.EnableItemMeshes(enable);
		}

		public void FallToGround(bool randomizePosition = false)
		{
			GrabbableObject.FallToGround(randomizePosition);
		}

		public bool PocketItem()
		{
			if (!IsHeld || (Object)(object)Holder.HeldItem != (Object)(object)this || IsTwoHanded)
			{
				return false;
			}
			GrabbableObject.PocketItem();
			return true;
		}

		public bool GiveTo(Player player, bool switchTo = true)
		{
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to give item to player on client.");
			}
			return player.Inventory.TryAddItem(this, switchTo);
		}

		public void InitializeScrap()
		{
			if (RoundManager.Instance.AnomalyRandom != null)
			{
				InitializeScrap((int)((float)RoundManager.Instance.AnomalyRandom.Next(ItemProperties.minValue, ItemProperties.maxValue) * RoundManager.Instance.scrapValueMultiplier));
			}
			else
			{
				InitializeScrap((int)((float)Random.Range(ItemProperties.minValue, ItemProperties.maxValue) * RoundManager.Instance.scrapValueMultiplier));
			}
		}

		public void InitializeScrap(int scrapValue)
		{
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to initialize scrap on client.");
			}
			ScrapValue = scrapValue;
			InitializeScrapClientRpc();
		}

		[ClientRpc]
		private void InitializeScrapClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1334565671u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1334565671u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			MeshFilter val3 = default(MeshFilter);
			if (((Component)GrabbableObject).gameObject.TryGetComponent<MeshFilter>(ref val3) && ItemProperties.meshVariants != null && ItemProperties.meshVariants.Length != 0)
			{
				if (RoundManager.Instance.ScrapValuesRandom != null)
				{
					val3.mesh = ItemProperties.meshVariants[RoundManager.Instance.ScrapValuesRandom.Next(ItemProperties.meshVariants.Length)];
				}
				else
				{
					val3.mesh = ItemProperties.meshVariants[0];
				}
			}
			MeshRenderer val4 = default(MeshRenderer);
			if (((Component)GrabbableObject).gameObject.TryGetComponent<MeshRenderer>(ref val4) && ItemProperties.materialVariants != null && ItemProperties.materialVariants.Length != 0)
			{
				if (RoundManager.Instance.ScrapValuesRandom != null)
				{
					((Renderer)val4).sharedMaterial = ItemProperties.materialVariants[RoundManager.Instance.ScrapValuesRandom.Next(ItemProperties.materialVariants.Length)];
				}
				else
				{
					((Renderer)val4).sharedMaterial = ItemProperties.materialVariants[0];
				}
			}
		}

		public static Item CreateAndSpawnItem(string itemName, bool andInitialize = true, Vector3 position = default(Vector3), Quaternion rotation = default(Quaternion))
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to create and spawn item on client.");
			}
			string name = itemName.ToLower();
			GameObject val = ((IEnumerable<Item>)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func<Item, bool>)((Item i) => i.itemName.ToLower().Contains(name)))?.spawnPrefab;
			if ((Object)(object)val != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(val, position, rotation);
				obj.GetComponent<NetworkObject>().Spawn(false);
				Item component = obj.GetComponent<Item>();
				if (component.IsScrap && andInitialize)
				{
					component.InitializeScrap();
				}
				return component;
			}
			return null;
		}

		public static Item CreateAndGiveItem(string itemName, Player player, bool andInitialize = true, bool switchTo = true)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				throw new NoAuthorityException("Tried to create and give item on client.");
			}
			string name = itemName.ToLower();
			GameObject val = ((IEnumerable<Item>)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func<Item, bool>)((Item i) => i.itemName.ToLower().Contains(name)))?.spawnPrefab;
			if ((Object)(object)val != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(val, Vector3.zero, default(Quaternion));
				obj.GetComponent<NetworkObject>().Spawn(false);
				Item component = obj.GetComponent<Item>();
				if (component.IsScrap && andInitialize)
				{
					component.InitializeScrap();
				}
				component.GiveTo(player, switchTo);
				return component;
			}
			return null;
		}

		private void Awake()
		{
			GrabbableObject = ((Component)this).GetComponent<GrabbableObject>();
			ScanNodeProperties = ((Component)GrabbableObject).gameObject.GetComponentInChildren<ScanNodeProperties>();
			Dictionary.Add(GrabbableObject, this);
		}

		private void CloneProperties()
		{
			Item itemProperties = Object.Instantiate<Item>(ItemProperties);
			if (hasNewProps)
			{
				Object.Destroy((Object)(object)ItemProperties);
			}
			GrabbableObject.itemProperties = itemProperties;
			hasNewProps = true;
		}

		public override void OnDestroy()
		{
			Dictionary.Remove(GrabbableObject);
			((NetworkBehaviour)this).OnDestroy();
		}

		public static Item GetOrAdd(GrabbableObject grabbableObject)
		{
			if (Dictionary.TryGetValue(grabbableObject, out var value))
			{
				return value;
			}
			return ((Component)grabbableObject).gameObject.AddComponent<Item>();
		}

		public static Item Get(GrabbableObject grabbableObject)
		{
			if (Dictionary.TryGetValue(grabbableObject, out var value))
			{
				return value;
			}
			return null;
		}

		public static bool TryGet(GrabbableObject grabbableObject, out Item item)
		{
			return Dictionary.TryGetValue(grabbableObject, out item);
		}

		public static Item Get(ulong netId)
		{
			return List.FirstOrDefault((Item i) => ((NetworkBehaviour)i).NetworkObjectId == netId);
		}

		public static bool TryGet(ulong netId, out Item item)
		{
			item = Get(netId);
			return (Object)(object)item != (Object)null;
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_Item()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(66243798u, new RpcReceiveHandler(__rpc_handler_66243798));
			NetworkManager.__rpc_func_table.Add(949135576u, new RpcReceiveHandler(__rpc_handler_949135576));
			NetworkManager.__rpc_func_table.Add(1528367091u, new RpcReceiveHandler(__rpc_handler_1528367091));
			NetworkManager.__rpc_func_table.Add(2688253945u, new RpcReceiveHandler(__rpc_handler_2688253945));
			NetworkManager.__rpc_func_table.Add(4227417717u, new RpcReceiveHandler(__rpc_handler_4227417717));
			NetworkManager.__rpc_func_table.Add(3866863385u, new RpcReceiveHandler(__rpc_handler_3866863385));
			NetworkManager.__rpc_func_table.Add(1050513218u, new RpcReceiveHandler(__rpc_handler_1050513218));
			NetworkManager.__rpc_func_table.Add(1334565671u, new RpcReceiveHandler(__rpc_handler_1334565671));
		}

		private static void __rpc_handler_66243798(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string grabbableNameClientRpc = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref grabbableNameClientRpc, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetGrabbableNameClientRpc(grabbableNameClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_949135576(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 itemPositionClientRpc = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref itemPositionClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetItemPositionClientRpc(itemPositionClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1528367091(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Quaternion itemRotationClientRpc = default(Quaternion);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref itemRotationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetItemRotationClientRpc(itemRotationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2688253945(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 itemScaleClientRpc = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref itemScaleClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetItemScaleClientRpc(itemScaleClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4227417717(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool isScrapClientRpc = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isScrapClientRpc, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetIsScrapClientRpc(isScrapClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3866863385(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int scrapValueClientRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref scrapValueClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).SetScrapValueClientRpc(scrapValueClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1050513218(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).RemoveFromHolderClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1334565671(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Item)(object)target).InitializeScrapClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "Item";
		}
	}
	public class Player : NetworkBehaviour
	{
		public class PlayerInventory : NetworkBehaviour
		{
			public Player Player { get; private set; }

			public Item[] Items => Player.PlayerController.ItemSlots.Select((GrabbableObject i) => (!((Object)(object)i != (Object)null)) ? null : Item.Dictionary[i]).ToArray();

			public int CurrentSlot
			{
				get
				{
					return Player.PlayerController.currentItemSlot;
				}
				set
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					if (Player.IsLocalPlayer)
					{
						SetSlotServerRpc(value);
					}
					else if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
					{
						SetSlotClientRpc(value);
					}
				}
			}

			[ServerRpc(RequireOwnership = false)]
			private void SetSlotServerRpc(int slot, ServerRpcParams serverRpcParams = default(ServerRpcParams))
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
					{
						FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1475903090u, serverRpcParams, (RpcDelivery)0);
						BytePacker.WriteValueBitPacked(val, slot);
						((NetworkBehaviour)this).__endSendServerRpc(ref val, 1475903090u, serverRpcParams, (RpcDelivery)0);
					}
					if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && serverRpcParams.Receive.SenderClientId == Player.ClientId)
					{
						SetSlotClientRpc(slot);
					}
				}
			}

			[ClientRpc]
			private void SetSlotClientRpc(int slot)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
					{
						ClientRpcParams val = default(ClientRpcParams);
						FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2977994897u, val, (RpcDelivery)0);
						BytePacker.WriteValueBitPacked(val2, slot);
						((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2977994897u, val, (RpcDelivery)0);
					}
					if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
					{
						Player.PlayerController.SwitchToItemSlot(slot, (GrabbableObject)null);
					}
				}
			}

			public int GetFirstEmptySlot()
			{
				return Player.PlayerController.FirstEmptyItemSlot();
			}

			public bool TryGetFirstEmptySlot(out int slot)
			{
				slot = Player.PlayerController.FirstEmptyItemSlot();
				return slot != -1;
			}

			public bool TryAddItem(Item item, bool switchTo = true)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to add item from client.");
				}
				if (TryGetFirstEmptySlot(out var slot))
				{
					if (item.IsTwoHanded && !Player.HasFreeHands)
					{
						return false;
					}
					if (item.IsHeld)
					{
						item.RemoveFromHolder();
					}
					((NetworkBehaviour)item).NetworkObject.ChangeOwnership(Player.ClientId);
					if (item.IsTwoHanded)
					{
						SetSlotAndItemClientRpc(slot, ((NetworkBehaviour)item).NetworkObjectId);
					}
					else if (switchTo && Player.HasFreeHands)
					{
						SetSlotAndItemClientRpc(slot, ((NetworkBehaviour)item).NetworkObjectId);
					}
					else if (Player.PlayerController.currentItemSlot == slot)
					{
						SetSlotAndItemClientRpc(slot, ((NetworkBehaviour)item).NetworkObjectId);
					}
					else
					{
						SetItemInSlotClientRpc(slot, ((NetworkBehaviour)item).NetworkObjectId);
					}
					return true;
				}
				return false;
			}

			public bool TryAddItemToSlot(Item item, int slot, bool switchTo = true)
			{
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: 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_0089: Unknown result type (might be due to invalid IL or missing references)
				if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
				{
					throw new NoAuthorityException("Tried to add item from client.");
				}
				if (slot < Player.PlayerController.ItemSlots.Length && (Object)(object)Player.PlayerController.ItemSlots[slot] == (Object)null)
				{
					if (item.IsTwoHanded && !Player.HasFreeHands)
					{
						return false;
					}
		

mods/AlexCodesGames-AdditionalContentFramework-1.0.3/plugins/AdditionalContentFramework.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AdditionalContentFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AdditionalContentFramework")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a49abfd9-fde7-4c8d-9798-d9cbe51418e3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AdditionalContentFramework;

[Serializable]
public class AdditionalSuitDef
{
	public string suitID;

	public string suitName;

	public string suitTexture;
}
[Serializable]
public class AdditionalContentModule
{
	public string resourceFolder;

	public List<AdditionalSuitDef> suitDefList = new List<AdditionalSuitDef>();

	public AdditionalContentModule(string folder)
	{
		resourceFolder = folder;
	}
}
[BepInPlugin("ACS.AdditionalContentFramework", "AdditionalContentFramework", "1.0.3")]
public class AdditionalContentFrameworkBase : BaseUnityPlugin
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class acgAdditionalContentPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void acsAdditionalContentPatch(StartOfRound __instance)
		{
			try
			{
				if (IsContentLoaded)
				{
					return;
				}
				AddLog("finding suit prefab...");
				for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val = __instance.unlockablesList.unlockables[i];
					if ((Object)(object)val.suitMaterial != (Object)null && val.alreadyUnlocked)
					{
						PrefabUnlockableSuit = val;
						AddLog("found suit prefab!");
						break;
					}
				}
				if (PrefabUnlockableSuit == null)
				{
					AddLog("ERROR: suit prefab was not found!");
					return;
				}
				AddLog("loading content modules...");
				string directoryName = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
				string[] directories = Directory.GetDirectories(directoryName);
				string[] array = directories;
				foreach (string path in array)
				{
					string[] directories2 = Directory.GetDirectories(path);
					string[] array2 = directories2;
					foreach (string path2 in array2)
					{
						DirectoryInfo directoryInfo = new DirectoryInfo(path2);
						if (directoryInfo.Name.StartsWith("res"))
						{
							LoadContentModule(path2);
						}
					}
					DirectoryInfo directoryInfo2 = new DirectoryInfo(path);
					if (directoryInfo2.Name.StartsWith("res"))
					{
						LoadContentModule(path);
					}
				}
				AddLog("loaded content modules! (count=" + ContentModules.Count + ")");
				AddLog("applying content modules...");
				foreach (AdditionalContentModule contentModule in ContentModules)
				{
					ApplyContentModule(__instance, contentModule);
				}
				AddLog("applied content modules!");
				IsContentLoaded = true;
			}
			catch (Exception ex)
			{
				AddLog("failed to load suits into lobby!\nERROR: " + ex);
			}
		}
	}

	private static AdditionalContentFrameworkBase Instance;

	private const string modGUID = "ACS.AdditionalContentFramework";

	private const string modName = "AdditionalContentFramework";

	private const string modVersion = "1.0.3";

	private readonly Harmony harmony = new Harmony("ACS.AdditionalContentFramework");

	private static ManualLogSource mls;

	public static bool IsContentLoaded = false;

	public static UnlockableItem PrefabUnlockableSuit = null;

	public static List<AdditionalContentModule> ContentModules = new List<AdditionalContentModule>();

	public string ModGUID => "ACS.AdditionalContentFramework";

	public string ModName => "AdditionalContentFramework";

	public string ModVersion => "1.0.3";

	public static void AddLog(string log)
	{
		mls.LogInfo((object)("AdditionalContentFramework - " + log));
	}

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		mls = Logger.CreateLogSource("ACS.AdditionalContentFramework");
		AddLog("initializing...");
		harmony.PatchAll();
		AddLog("initialized!");
	}

	public static AdditionalSuitDef LoadContentPiece_Suit(string defStr)
	{
		try
		{
			return JsonUtility.FromJson<AdditionalSuitDef>(defStr);
		}
		catch (Exception ex)
		{
			AddLog("failed to load content module piece (suitDef='" + defStr + "')!\nERROR: " + ex);
			return null;
		}
	}

	public static void LoadContentModule(string path)
	{
		try
		{
			AddLog("attempting to load suits from path:" + path);
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), path);
			string text2 = Path.Combine(text, "suit-defs.json");
			AddLog("attempting to parse json file: " + text2);
			string text3 = File.ReadAllText(text2);
			if (text3 == null)
			{
				AddLog("ERROR: json file was not found or invalid");
				return;
			}
			AdditionalContentModule additionalContentModule = new AdditionalContentModule(text);
			string[] array = text3.Split(new char[1] { '[' });
			array = array[1].Split(new char[1] { ']' });
			array = array[0].Split(new char[1] { '{' });
			for (int i = 1; i < array.Length; i++)
			{
				string text4 = "{" + array[i].Trim();
				if (i != array.Length - 1)
				{
					text4 = text4.Substring(0, text4.Length - 1);
				}
				try
				{
					AdditionalSuitDef additionalSuitDef = JsonUtility.FromJson<AdditionalSuitDef>(text4);
					if (additionalSuitDef != null)
					{
						additionalContentModule.suitDefList.Add(additionalSuitDef);
						AddLog("\tloaded suit def: " + additionalSuitDef.suitName);
					}
				}
				catch (Exception ex)
				{
					AddLog("failed to load content module piece (json='" + text4 + "')!\nERROR: " + ex);
				}
			}
			ContentModules.Add(additionalContentModule);
			AddLog("finished loading suits from path:" + path);
		}
		catch (Exception ex2)
		{
			AddLog("failed to load content module!\nERROR: " + ex2);
		}
	}

	public static void ApplyContentModule(StartOfRound __instance, AdditionalContentModule suitDefManifest)
	{
		AddLog("applying additional content module from: " + suitDefManifest.resourceFolder + "...");
		foreach (AdditionalSuitDef suitDef in suitDefManifest.suitDefList)
		{
			AddSuitToRack(__instance, suitDef, suitDefManifest.resourceFolder);
		}
		AddLog("applyed additional content module from: " + suitDefManifest.resourceFolder + "!");
	}

	public static void AddSuitToRack(StartOfRound __instance, AdditionalSuitDef suitDef, string resourcePath)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		AddLog("adding suit to rack {id=" + suitDef.suitID + ", name=" + suitDef.suitName + "}...");
		UnlockableItem val = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)PrefabUnlockableSuit));
		Texture2D val2 = new Texture2D(2, 2);
		ImageConversion.LoadImage(val2, File.ReadAllBytes(Path.Combine(resourcePath, suitDef.suitTexture)));
		Material val3 = Object.Instantiate<Material>(val.suitMaterial);
		val3.mainTexture = (Texture)(object)val2;
		val.suitMaterial = val3;
		val.unlockableName = suitDef.suitName;
		__instance.unlockablesList.unlockables.Add(val);
		AddLog("added suit to rack {id=" + suitDef.suitID + ", name=" + suitDef.suitName + "}! (new unlockable count is " + __instance.unlockablesList.unlockables.Count + ")");
	}
}

mods/FlipMods-ReservedFlashlightSlot-1.6.2/ReservedFlashlightSlot.dll

Decompiled 10 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using ReservedFlashlightSlot.Patches;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedFlashlightSlot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedFlashlightSlot")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5b7d6563-4e51-4a69-bcf9-fa1dea6eff75")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedFlashlightSlot
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> activateFlashlightKey;

		public static ConfigEntry<bool> hideFlashlightMeshShoulder;

		public static string activateFlashlightDisplayName;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			activateFlashlightKey = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedFlashlightSlot", "ActivateFlashlightKey", "<Keyboard>/f", "This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)");
			hideFlashlightMeshShoulder = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedFlashlightSlot", "HideFlashlightOnShoulder", false, "Hides the flashlight mesh while on your shoulder. Only applies in scenarios where you can view your player in third person.");
			activateFlashlightDisplayName = GetDisplayName(activateFlashlightKey.Value);
			currentConfigEntries.Add(((ConfigEntryBase)activateFlashlightKey).Definition.Key, (ConfigEntryBase)(object)activateFlashlightKey);
			currentConfigEntries.Add(((ConfigEntryBase)hideFlashlightMeshShoulder).Definition.Key, (ConfigEntryBase)(object)hideFlashlightMeshShoulder);
			TryRemoveOldConfigSettings();
		}

		public static string GetDisplayName(string key)
		{
			key = key.Replace("<Keyboard>/", "");
			key = key.Replace("<Mouse>/", "");
			string text = key;
			text = text.Replace("leftAlt", "Alt");
			text = text.Replace("rightAlt", "Alt");
			text = text.Replace("leftCtrl", "Ctrl");
			text = text.Replace("rightCtrl", "Ctrl");
			text = text.Replace("leftShift", "Shift");
			text = text.Replace("rightShift", "Shift");
			text = text.Replace("leftButton", "LMB");
			text = text.Replace("rightButton", "RMB");
			return text.Replace("middleButton", "MMB");
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("FlipMods.ReservedFlashlightSlot", "ReservedFlashlightSlot", "1.6.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private Harmony _harmony;

		public static ReservedItemInfo proFlashlightInfo = new ReservedItemInfo("Pro-flashlight", 120, true, true, true, true);

		public static ReservedItemInfo flashlightInfo = new ReservedItemInfo("Flashlight", 120, true, true, true, true);

		public static ReservedItemInfo laserPointerInfo = new ReservedItemInfo("Laser pointer", 120, true, true, true, true);

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("ReservedFlashlightSlot");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ReservedFlashlightSlot loaded");
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogWarning(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedFlashlightSlot";

		public const string PLUGIN_NAME = "ReservedFlashlightSlot";

		public const string PLUGIN_VERSION = "1.6.2";
	}
}
namespace ReservedFlashlightSlot.Input
{
	internal class IngameKeybinds : LcInputActions
	{
		internal static IngameKeybinds Instance = new IngameKeybinds();

		[InputAction("<Keyboard>/f", Name = "[ReservedItemSlots]\nToggle flashlight")]
		public InputAction ToggleFlashlightHotkey { get; set; }

		internal static InputActionAsset GetAsset()
		{
			return ((LcInputActions)Instance).Asset;
		}
	}
	internal class InputUtilsCompat
	{
		internal static InputActionAsset Asset => IngameKeybinds.GetAsset();

		internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils");

		public static InputAction ToggleFlashlightHotkey => IngameKeybinds.Instance.ToggleFlashlightHotkey;
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static InputActionAsset Asset;

		public static InputActionMap ActionMap;

		private static InputAction ActivateFlashlightAction;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void AddToKeybindMenu()
		{
			InitKeybinds();
		}

		public static void InitKeybinds()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log("Initializing hotkeys.");
			if (InputUtilsCompat.Enabled)
			{
				Asset = InputUtilsCompat.Asset;
				ActionMap = Asset.actionMaps[0];
				ActivateFlashlightAction = InputUtilsCompat.ToggleFlashlightHotkey;
			}
			else
			{
				Asset = new InputActionAsset();
				ActionMap = new InputActionMap("ReservedItemSlots");
				InputActionSetupExtensions.AddActionMap(Asset, ActionMap);
				ActivateFlashlightAction = InputActionSetupExtensions.AddAction(ActionMap, "ReservedItemSlots.ToggleFlashlight", (InputActionType)0, ConfigSettings.activateFlashlightKey.Value, (string)null, (string)null, (string)null, (string)null);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable()
		{
			Asset.Enable();
			ActivateFlashlightAction.performed += OnActivateFlashlightPerformed;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable()
		{
			Asset.Disable();
			ActivateFlashlightAction.performed -= OnActivateFlashlightPerformed;
		}

		private static void OnActivateFlashlightPerformed(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject))
			{
				return;
			}
			FlashlightItem mainFlashlight = FlashlightPatcher.GetMainFlashlight(localPlayerController);
			if (((CallbackContext)(ref context)).performed && !((Object)(object)mainFlashlight == (Object)null) && !ShipBuildModeManager.Instance.InBuildMode && !localPlayerController.inTerminalMenu)
			{
				float num = (float)Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").GetValue();
				if (!(num < 0.075f))
				{
					((GrabbableObject)mainFlashlight).UseItemOnClient(!((GrabbableObject)mainFlashlight).isBeingUsed);
					Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").SetValue((object)0);
				}
			}
		}
	}
}
namespace ReservedFlashlightSlot.Patches
{
	[HarmonyPatch]
	internal static class FlashlightPatcher
	{
		public static Vector3 playerShoulderPositionOffset = new Vector3(0.2f, 0.25f, 0f);

		public static Vector3 playerShoulderRotationOffset = new Vector3(90f, 0f, 0f);

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static PlayerControllerB GetPreviousPlayerHeldBy(FlashlightItem flashlightItem)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (PlayerControllerB)Traverse.Create((object)flashlightItem).Field("previousPlayerHeldBy").GetValue();
		}

		public static FlashlightItem GetMainFlashlight(PlayerControllerB playerController)
		{
			return GetCurrentlySelectedFlashlight(playerController) ?? GetReservedFlashlight(playerController);
		}

		public static FlashlightItem GetReservedFlashlight(PlayerControllerB playerController)
		{
			ReservedPlayerData value;
			return (FlashlightItem)((SyncManager.syncReservedItemsList.Contains(Plugin.flashlightInfo) && PlayerPatcher.allPlayerData.TryGetValue(playerController, out value)) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static FlashlightItem GetCurrentlySelectedFlashlight(PlayerControllerB playerController)
		{
			return (FlashlightItem)((playerController.currentItemSlot >= 0 && playerController.currentItemSlot < playerController.ItemSlots.Length) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static bool IsFlashlightOn(PlayerControllerB playerController)
		{
			return ((GrabbableObject)(GetMainFlashlight(playerController)?)).isBeingUsed ?? false;
		}

		[HarmonyPatch(typeof(FlashlightItem), "SwitchFlashlight")]
		[HarmonyPostfix]
		public static void OnSwitchOnOffFlashlight(bool on, FlashlightItem __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				UpdateAllFlashlightStates(((GrabbableObject)__instance).playerHeldBy, on);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketItem")]
		[HarmonyPostfix]
		public static void OnPocketFlashlightLocal(FlashlightItem __instance)
		{
			OnPocketFlashlight(__instance, ((GrabbableObject)__instance).isBeingUsed);
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketFlashlightClientRpc")]
		[HarmonyPrefix]
		public static void OnPocketFlashlightClientRpc(bool stillUsingFlashlight, FlashlightItem __instance)
		{
			if (NetworkHelper.IsValidClientRpcExecStage((NetworkBehaviour)(object)__instance) && !((NetworkBehaviour)__instance).IsOwner && !((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) && !((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController))
			{
				OnPocketFlashlight(__instance, stillUsingFlashlight);
			}
		}

		private static void OnPocketFlashlight(FlashlightItem flashlightItem, bool stillUsingFlashlight = false)
		{
			if ((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)null)
			{
				return;
			}
			FlashlightItem currentlySelectedFlashlight = GetCurrentlySelectedFlashlight(((GrabbableObject)flashlightItem).playerHeldBy);
			FlashlightItem reservedFlashlight = GetReservedFlashlight(((GrabbableObject)flashlightItem).playerHeldBy);
			bool flag = stillUsingFlashlight || ((Object)(object)currentlySelectedFlashlight != (Object)null && ((GrabbableObject)currentlySelectedFlashlight).isBeingUsed);
			if ((Object)(object)currentlySelectedFlashlight != (Object)null && ((GrabbableObject)currentlySelectedFlashlight).isBeingUsed)
			{
				((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = null;
			}
			else if (((GrabbableObject)flashlightItem).isBeingUsed)
			{
				((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)flashlightItem;
			}
			else if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight == (Object)null || !((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight.isBeingUsed))
			{
				((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
			}
			MeshRenderer[] componentsInChildren = ((Component)flashlightItem).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = (((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)(object)localPlayerController) ? 23 : 6);
				}
			}
			if ((Object)(object)flashlightItem == (Object)(object)reservedFlashlight)
			{
				((GrabbableObject)flashlightItem).parentObject = ((GrabbableObject)flashlightItem).playerHeldBy.playerGlobalHead.parent;
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "EquipItem")]
		[HarmonyPostfix]
		public static void OnEquipFlashlight(FlashlightItem __instance)
		{
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null)
			{
				return;
			}
			bool mainFlashlightActive = ((Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight != (Object)null && ((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight.isBeingUsed) || ((GrabbableObject)__instance).isBeingUsed;
			FlashlightItem reservedFlashlight = GetReservedFlashlight(((GrabbableObject)__instance).playerHeldBy);
			if (((GrabbableObject)__instance).isBeingUsed || (Object)(object)__instance == (Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight)
			{
				((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight = null;
			}
			else if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight == (Object)null || !((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight.isBeingUsed))
			{
				((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = 6;
				}
			}
			((GrabbableObject)__instance).parentObject = (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController) ? ((GrabbableObject)__instance).playerHeldBy.localItemHolder : ((GrabbableObject)__instance).playerHeldBy.serverItemHolder);
			UpdateAllFlashlightStates(((GrabbableObject)__instance).playerHeldBy, mainFlashlightActive);
		}

		[HarmonyPatch(typeof(FlashlightItem), "DiscardItem")]
		[HarmonyPrefix]
		public static void ResetPocketedFlashlight(FlashlightItem __instance)
		{
			PlayerControllerB previousPlayerHeldBy = GetPreviousPlayerHeldBy(__instance);
			if ((Object)(object)previousPlayerHeldBy == (Object)null)
			{
				return;
			}
			FlashlightItem reservedFlashlight = GetReservedFlashlight(previousPlayerHeldBy);
			if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)__instance == (Object)(object)previousPlayerHeldBy.pocketedFlashlight || (Object)(object)previousPlayerHeldBy.pocketedFlashlight == (Object)null))
			{
				previousPlayerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = 6;
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void SetPositionOffset(GrabbableObject __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is FlashlightItem && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance.parentObject != (Object)null && __instance.isPocketed && (Object)(object)__instance == (Object)(object)GetReservedFlashlight(__instance.playerHeldBy) && (Object)(object)__instance != (Object)(object)GetCurrentlySelectedFlashlight(__instance.playerHeldBy))
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = ((Component)__instance.parentObject).transform.rotation * Quaternion.Euler(playerShoulderRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * playerShoulderPositionOffset;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EnableItemMeshes")]
		[HarmonyPrefix]
		public static void OnEnableItemMeshes(ref bool enable, GrabbableObject __instance)
		{
			if (__instance is FlashlightItem && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance == (Object)(object)GetReservedFlashlight(__instance.playerHeldBy) && !ConfigSettings.hideFlashlightMeshShoulder.Value && !ReservedItemPatcher.ReservedItemIsBeingGrabbed(__instance))
			{
				enable = true;
			}
		}

		private static void UpdateAllFlashlightStates(PlayerControllerB playerController, bool mainFlashlightActive = true)
		{
			FlashlightItem mainFlashlight = GetMainFlashlight(playerController);
			if ((Object)(object)mainFlashlight == (Object)null)
			{
				((Behaviour)playerController.helmetLight).enabled = false;
				mainFlashlightActive = false;
			}
			else
			{
				playerController.ChangeHelmetLight(mainFlashlight.flashlightTypeID, mainFlashlightActive && (Object)(object)playerController == (Object)(object)localPlayerController && (Object)(object)playerController.ItemSlots[playerController.currentItemSlot] != (Object)(object)mainFlashlight);
			}
			for (int i = 0; i < playerController.ItemSlots.Length; i++)
			{
				GrabbableObject obj = playerController.ItemSlots[i];
				FlashlightItem val = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					UpdateFlashlightState(val, (Object)(object)val == (Object)(object)mainFlashlight && mainFlashlightActive);
				}
			}
		}

		private static void UpdateFlashlightState(FlashlightItem flashlightItem, bool active)
		{
			if (!((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)null))
			{
				PlayerControllerB playerHeldBy = ((GrabbableObject)flashlightItem).playerHeldBy;
				((GrabbableObject)flashlightItem).isBeingUsed = active;
				bool flag = (Object)(object)playerHeldBy != (Object)(object)localPlayerController || (Object)(object)playerHeldBy.ItemSlots[playerHeldBy.currentItemSlot] == (Object)(object)flashlightItem;
				((Behaviour)flashlightItem.flashlightBulb).enabled = active && flag;
				((Behaviour)flashlightItem.flashlightBulbGlow).enabled = active && flag;
				flashlightItem.usingPlayerHelmetLight = active && !flag;
			}
		}
	}
	[HarmonyPatch]
	public class MaskedEnemyPatcher
	{
		public static Dictionary<MaskedPlayerEnemy, GameObject> heldFlashlightsByEnemy = new Dictionary<MaskedPlayerEnemy, GameObject>();

		public static HashSet<MaskedPlayerEnemy> spawnedEnemies = new HashSet<MaskedPlayerEnemy>();

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "OnDestroy")]
		[HarmonyPrefix]
		public static void OnDestroy(MaskedPlayerEnemy __instance)
		{
			if (heldFlashlightsByEnemy.TryGetValue(__instance, out var value))
			{
				Plugin.LogWarning("Destroying flashlight. Enemy destroyed.");
				Object.DestroyImmediate((Object)(object)value);
				spawnedEnemies.Remove(__instance);
			}
			heldFlashlightsByEnemy.Remove(__instance);
		}

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "LateUpdate")]
		[HarmonyPostfix]
		public static void ShowWalkieOnEnemy(MaskedPlayerEnemy __instance)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			if (!spawnedEnemies.Contains(__instance) && SyncManager.syncReservedItemsList.Contains(Plugin.proFlashlightInfo) && !((EnemyAI)__instance).isEnemyDead && !heldFlashlightsByEnemy.ContainsKey(__instance) && (Object)(object)__instance.mimickingPlayer != (Object)null && PlayerPatcher.allPlayerData.TryGetValue(__instance.mimickingPlayer, out var value))
			{
				spawnedEnemies.Add(__instance);
				FlashlightItem reservedFlashlight = FlashlightPatcher.GetReservedFlashlight(value.playerController);
				if ((Object)(object)reservedFlashlight != (Object)null)
				{
					Plugin.LogWarning("OnMaskedEnemySpawn - MimickingPlayer: " + ((Object)value.playerController).name + " - Spawning flashlight object on enemy.");
					GameObject val = new GameObject("ReservedFlashlight [MaskedEnemy]");
					Light[] componentsInChildren = ((Component)reservedFlashlight).GetComponentsInChildren<Light>();
					MeshRenderer mainObjectRenderer = ((GrabbableObject)reservedFlashlight).mainObjectRenderer;
					Light[] array = componentsInChildren;
					foreach (Light val2 in array)
					{
						Light component = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.localPosition, ((Component)val2).transform.localRotation, val.transform).GetComponent<Light>();
						((Behaviour)component).enabled = true;
						((Component)component).gameObject.layer = 6;
					}
					MeshRenderer component2 = Object.Instantiate<GameObject>(((Component)mainObjectRenderer).gameObject, ((Component)mainObjectRenderer).transform.localPosition, ((Component)mainObjectRenderer).transform.localRotation, val.transform).GetComponent<MeshRenderer>();
					((Renderer)component2).enabled = true;
					((Component)component2).gameObject.layer = 6;
					val.transform.localScale = ((Component)reservedFlashlight).transform.localScale;
					heldFlashlightsByEnemy.Add(__instance, val);
				}
			}
			if (heldFlashlightsByEnemy.TryGetValue(__instance, out var value2))
			{
				if (((EnemyAI)__instance).isEnemyDead)
				{
					Plugin.LogWarning("Destroying flashlight. Enemy dead.");
					Object.DestroyImmediate((Object)(object)value2);
					spawnedEnemies.Remove(__instance);
					heldFlashlightsByEnemy.Remove(__instance);
				}
				else
				{
					Transform parent = ((EnemyAI)__instance).eye.parent.parent;
					value2.transform.rotation = parent.rotation * Quaternion.Euler(FlashlightPatcher.playerShoulderRotationOffset);
					value2.transform.position = parent.position + parent.rotation * FlashlightPatcher.playerShoulderPositionOffset;
				}
			}
		}
	}
}

mods/FlipMods-ReservedItemSlotCore-1.8.14/ReservedItemSlotCore.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using ReservedItemSlotCore.Compatibility;
using ReservedItemSlotCore.Config;
using ReservedItemSlotCore.Input;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedItemSlotCore")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedItemSlotCore")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("238ce080-e339-46b6-9b08-992a950453a1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("ReservedFlashlightSlot")]
[assembly: InternalsVisibleTo("ReservedWalkieSlot")]
[assembly: InternalsVisibleTo("ReservedWeaponSlot")]
[assembly: InternalsVisibleTo("ReservedUtilitySlot")]
[assembly: InternalsVisibleTo("ReservedSprayPaintSlot")]
[assembly: InternalsVisibleTo("ReservedBoomboxSlot")]
[assembly: InternalsVisibleTo("ReservedPersonalBoomboxSlot")]
[assembly: InternalsVisibleTo("ReservedKeySlot")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedItemSlotCore
{
	internal class ReservedPlayerData
	{
		public PlayerControllerB playerController;

		public ReservedItemInfo grabbingReservedItemInfo = null;

		public GrabbableObject grabbingReservedItem = null;

		public int previousHotbarIndex = -1;

		public bool inReservedHotbarSlots = false;

		public int hotbarSize = 4;

		public int reservedHotbarStartIndex = 4;

		public bool isLocalPlayer => (Object)(object)playerController != (Object)null && (Object)(object)playerController == (Object)(object)StartOfRound.Instance?.localPlayerController;

		public int currentItemSlot => playerController.currentItemSlot;

		public bool currentItemSlotIsReserved => currentItemSlot >= reservedHotbarStartIndex && currentItemSlot < reservedHotbarStartIndex + SyncManager.numReservedItemSlots;

		public GrabbableObject previouslyHeldItem => (previousHotbarIndex >= 0 && previousHotbarIndex < playerController.ItemSlots.Length) ? playerController.ItemSlots[previousHotbarIndex] : null;

		public bool throwingObject => (bool)Traverse.Create((object)playerController).Field("throwingObject").GetValue();

		public int reservedHotbarEndIndexExcluded => reservedHotbarStartIndex + SyncManager.numReservedItemSlots;

		public bool IsReservedItemSlot(int index)
		{
			return index >= reservedHotbarStartIndex && index < reservedHotbarStartIndex + SyncManager.numReservedItemSlots;
		}

		public int GetNumHeldReservedItems()
		{
			int num = 0;
			for (int i = 0; i < playerController.ItemSlots.Length; i++)
			{
				GrabbableObject val = playerController.ItemSlots[i];
				num += (((Object)(object)val != (Object)null && SyncManager.IsReservedItem(val.itemProperties.itemName)) ? 1 : 0);
			}
			return num;
		}

		public GrabbableObject GetReservedItem(ReservedItemInfo itemInfo)
		{
			if (itemInfo == null)
			{
				return null;
			}
			int num = reservedHotbarStartIndex + itemInfo.reservedItemIndex;
			return (num >= 0 && num < playerController.ItemSlots.Length) ? playerController.ItemSlots[num] : null;
		}

		public string DumpData()
		{
			if ((Object)(object)playerController == (Object)null)
			{
				Plugin.LogError("PLAYER NULL");
			}
			if (SyncManager.syncReservedItemSlotReps == null)
			{
				Plugin.LogError("REPS NULL");
			}
			string text = "[ReservedPlayerData Dump]\nPlayer: " + ((Object)playerController).name + (isLocalPlayer ? " [LocalPlayer]" : "") + "\nCurrentItemSlot: " + currentItemSlot + "\nRegisteredHotbarSize: " + hotbarSize + "\nActualHotbarSize: " + playerController.ItemSlots.Length + "\nCurrentlyGrabbingReservedItem: " + ((grabbingReservedItemInfo != null) ? grabbingReservedItemInfo.itemName : "false") + "\nReservedHotbarStartIndex: " + reservedHotbarStartIndex + "\n" + (isLocalPlayer ? ("NumItemSlotsHUD: " + HUDManager.Instance.itemSlotIconFrames.Length + "\n") : "") + "ItemsInInventory: [";
			for (int i = 0; i < playerController.ItemSlots.Length; i++)
			{
				if (i > 0)
				{
					text += ", ";
				}
				text += (("[" + i + "] " + (object)playerController.ItemSlots[i] != null) ? ((Object)playerController.ItemSlots[i]).name : "Empty");
			}
			return text + "]\nNumHeldReservedItems: " + GetNumHeldReservedItems();
		}
	}
	[BepInPlugin("FlipMods.ReservedItemSlotCore", "ReservedItemSlotCore", "1.8.14")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		private static ManualLogSource logger;

		public static Dictionary<string, ReservedItemInfo> reservedItemsDictDefault => ReservedItemInfo.reservedItemsDictDefault;

		public static List<ReservedItemInfo> reservedItemsListDefault => ReservedItemInfo.reservedItemsListDefault;

		public static List<ReservedItemInfo> reservedItemSlotRepsDefault => ReservedItemInfo.reservedItemSlotRepsDefault;

		public static int numReservedItemSlotsDefault => ReservedItemInfo.numReservedItemSlotsDefault;

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			instance = this;
			CreateCustomLogger();
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("ReservedItemSlotCore");
			_harmony.PatchAll();
			Log("ReservedItemSlotCore loaded");
		}

		private void CreateCustomLogger()
		{
			try
			{
				logger = Logger.CreateLogSource($"{((BaseUnityPlugin)this).Info.Metadata.Name}-{((BaseUnityPlugin)this).Info.Metadata.Version}");
			}
			catch
			{
				logger = ((BaseUnityPlugin)this).Logger;
			}
		}

		public static void Log(string message)
		{
			logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			logger.LogWarning((object)message);
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		public static bool IsReservedItemDefault(string itemName)
		{
			return reservedItemsDictDefault.ContainsKey(itemName);
		}

		public static ReservedItemInfo GetReservedItemInfoDefault(string itemName)
		{
			return IsReservedItemDefault(itemName) ? reservedItemsDictDefault[itemName] : null;
		}

		public static ReservedItemInfo GetReservedItemInfoDefault(GrabbableObject item)
		{
			return ((Object)(object)item != (Object)null) ? GetReservedItemInfoDefault(item.itemProperties.itemName) : null;
		}
	}
	internal class ReservedItemInfo
	{
		public static Dictionary<string, ReservedItemInfo> reservedItemsDictDefault = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemsListDefault = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemSlotRepsDefault = new List<ReservedItemInfo>();

		public static Dictionary<string, ReservedItemInfo> reservedItemsDict = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemsList = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemSlotReps = new List<ReservedItemInfo>();

		public string itemName = "";

		public HashSet<string> acceptedItemNames;

		public int hotbarSlotPriority = 0;

		public int reservedItemIndex = 0;

		public bool forceUpdateCanBeGrabbedBeforeGameStart = false;

		public bool canBeGrabbedBeforeGameStart = false;

		public bool forceUpdateRequiresBattery = false;

		public bool requiresBattery = false;

		public static int numReservedItemSlotsDefault => reservedItemSlotRepsDefault.Count;

		public ReservedItemInfo()
		{
		}

		public ReservedItemInfo(string itemName, int hotbarSlotPriority, bool forceUpdateCanBeGrabbedBeforeGameStart = false, bool canBeGrabbedBeforeGameStart = false, bool forceUpdateRequiresBattery = false, bool requiresBattery = false)
		{
			this.itemName = itemName;
			this.hotbarSlotPriority = hotbarSlotPriority;
			AddItemInfoToList(this);
			ReservedItemInfo info = new ReservedItemInfo(this);
			AddItemInfoToList(info, reservedItemsListDefault, reservedItemsDictDefault, reservedItemSlotRepsDefault);
		}

		public static void AddItemInfoToList(ReservedItemInfo info, List<ReservedItemInfo> _reservedItemsList = null, Dictionary<string, ReservedItemInfo> _reservedItemsDict = null, List<ReservedItemInfo> _reservedItemSlotReps = null)
		{
			if (_reservedItemsList == null)
			{
				_reservedItemsList = reservedItemsList;
			}
			if (_reservedItemsDict == null)
			{
				_reservedItemsDict = reservedItemsDict;
			}
			if (_reservedItemSlotReps == null)
			{
				_reservedItemSlotReps = reservedItemSlotReps;
			}
			if (!_reservedItemsDict.ContainsKey(info.itemName))
			{
				_reservedItemsDict.Add(info.itemName, info);
				_reservedItemsList.Add(info);
				int i;
				for (i = 0; i < _reservedItemSlotReps.Count; i++)
				{
					ReservedItemInfo reservedItemInfo = _reservedItemSlotReps[i];
					if (info.hotbarSlotPriority >= reservedItemInfo.hotbarSlotPriority)
					{
						break;
					}
				}
				info.reservedItemIndex = i;
				if (i == _reservedItemSlotReps.Count || info.hotbarSlotPriority != _reservedItemSlotReps[i].hotbarSlotPriority)
				{
					info.acceptedItemNames = new HashSet<string> { info.itemName };
					_reservedItemSlotReps.Insert(i, info);
					{
						foreach (ReservedItemInfo _reservedItems in _reservedItemsList)
						{
							if (info != _reservedItems && _reservedItems.reservedItemIndex >= i)
							{
								_reservedItems.reservedItemIndex++;
							}
						}
						return;
					}
				}
				info.acceptedItemNames = _reservedItemSlotReps[i].acceptedItemNames;
				info.acceptedItemNames.Add(info.itemName);
			}
			else
			{
				Plugin.Log($"Tried to add duplicate item name to the ReservedItems list: {info.itemName}. Sorting instead");
			}
		}

		public ReservedItemInfo(ReservedItemInfo copyFrom)
		{
			itemName = copyFrom.itemName;
			hotbarSlotPriority = copyFrom.hotbarSlotPriority;
			reservedItemIndex = copyFrom.reservedItemIndex;
			forceUpdateCanBeGrabbedBeforeGameStart = copyFrom.forceUpdateCanBeGrabbedBeforeGameStart;
			canBeGrabbedBeforeGameStart = copyFrom.canBeGrabbedBeforeGameStart;
			forceUpdateRequiresBattery = copyFrom.forceUpdateRequiresBattery;
			requiresBattery = copyFrom.requiresBattery;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedItemSlotCore";

		public const string PLUGIN_NAME = "ReservedItemSlotCore";

		public const string PLUGIN_VERSION = "1.8.14";
	}
}
namespace ReservedItemSlotCore.Config
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> focusReservedHotbarHotkey;

		public static ConfigEntry<bool> toggleFocusReservedHotbar;

		public static ConfigEntry<bool> preventReservedItemSlotFade;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			focusReservedHotbarHotkey = AddConfigEntry<string>(((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedItemSlotCore", "FocusReservedItemSlotsHotkey", "<Keyboard>/leftAlt", "This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)"));
			toggleFocusReservedHotbar = AddConfigEntry<bool>(((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedItemSlotCore", "ToggleFocusReservedHotbar", false, "If set to true, swapping to the reserved hotbar slots will be toggled when pressing the hotkey rather than while holding the hotkey. Setting this option to true may have bugs at this current time."));
			preventReservedItemSlotFade = AddConfigEntry<bool>(((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedItemSlotCore", "PreventReservedHotbarSlotFade", false, "If true, the reserved hotbar slots will not fade with the rest of the default slots."));
			TryRemoveOldConfigSettings();
		}

		public static ConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			currentConfigEntries.Add(((ConfigEntryBase)configEntry).Definition.Key, (ConfigEntryBase)(object)configEntry);
			return configEntry;
		}

		public static string GetDisplayName(string key)
		{
			try
			{
				if (key.Length <= 1)
				{
					return key;
				}
				int num = key.IndexOf(">/");
				key = ((num >= 0) ? key.Substring(num + 2) : key);
				string text = key.ToLower();
				text = text.Replace("leftalt", "Alt");
				text = text.Replace("rightalt", "Alt");
				text = text.Replace("leftctrl", "Ctrl");
				text = text.Replace("rightctrl", "Ctrl");
				text = text.Replace("leftshift", "Shift");
				text = text.Replace("rightshift", "Shift");
				text = text.Replace("leftbutton", "LMB");
				text = text.Replace("rightbutton", "RMB");
				text = text.Replace("middlebutton", "MMB");
				text = text.Replace("lefttrigger", "LT");
				text = text.Replace("righttrigger", "RT");
				text = text.Replace("leftshoulder", "LB");
				text = text.Replace("rightshoulder", "RB");
				text = text.Replace("leftstickpress", "LS");
				text = text.Replace("rightstickpress", "RS");
				try
				{
					text = char.ToUpper(text[0]) + text.Substring(1);
				}
				catch
				{
				}
				return text;
			}
			catch
			{
				return "";
			}
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
}
namespace ReservedItemSlotCore.Networking
{
	public static class NetworkHelper
	{
		private static int NONE_EXEC_STAGE = 0;

		private static int SERVER_EXEC_STAGE = 1;

		private static int CLIENT_EXEC_STAGE = 2;

		public static int GetExecStage(NetworkBehaviour __instance)
		{
			return (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
		}

		public static bool IsClientExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == CLIENT_EXEC_STAGE;
		}

		public static bool IsServerExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == SERVER_EXEC_STAGE;
		}

		public static bool IsValidClientRpcExecStage(NetworkBehaviour __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				return false;
			}
			int num = (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
			if ((singleton.IsServer || singleton.IsHost) && num != 2)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class SyncManager
	{
		public static PlayerControllerB localPlayerController;

		public static bool isSynced = false;

		public static bool canUseModDisabledOnHost = true;

		public static Dictionary<string, ReservedItemInfo> syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> syncReservedItemsList = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> syncReservedItemSlotReps = new List<ReservedItemInfo>();

		public static int numReservedItemSlots => syncReservedItemSlotReps.Count;

		public static bool IsReservedItem(string itemName)
		{
			return syncReservedItemsDict.ContainsKey(itemName);
		}

		public static bool TryGetReservedItemInfo(string itemName, out ReservedItemInfo info)
		{
			info = null;
			if (IsReservedItem(itemName))
			{
				info = syncReservedItemsDict[itemName];
				return true;
			}
			return false;
		}

		public static bool TryGetReservedItemInfo(GrabbableObject item, out ReservedItemInfo info)
		{
			info = null;
			return (Object)(object)item != (Object)null && TryGetReservedItemInfo(item.itemProperties.itemName, out info);
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void ResetValues()
		{
			isSynced = false;
			localPlayerController = null;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init(PlayerControllerB __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			localPlayerController = __instance;
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-OnSwapHotbarClientRpc", new HandleNamedMessageDelegate(OnSwapHotbarClientRpc));
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-RequestSyncClientRpc", new HandleNamedMessageDelegate(RequestSyncClientRpc));
			if (NetworkManager.Singleton.IsServer)
			{
				isSynced = true;
				syncReservedItemsDict = ReservedItemInfo.reservedItemsDict;
				syncReservedItemsList = ReservedItemInfo.reservedItemsList;
				syncReservedItemSlotReps = ReservedItemInfo.reservedItemSlotReps;
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-OnSwapHotbarServerRpc", new HandleNamedMessageDelegate(OnSwapHotbarServerRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-RequestSyncServerRpc", new HandleNamedMessageDelegate(RequestSyncServerRpc));
				{
					foreach (ReservedItemInfo syncReservedItems in syncReservedItemsList)
					{
						ReservedItemInfo reservedItemInfo = ReservedItemInfo.reservedItemsDictDefault[syncReservedItems.itemName];
						syncReservedItems.hotbarSlotPriority = reservedItemInfo.hotbarSlotPriority;
						syncReservedItems.reservedItemIndex = reservedItemInfo.reservedItemIndex;
					}
					return;
				}
			}
			isSynced = false;
			if (canUseModDisabledOnHost)
			{
				syncReservedItemsDict = ReservedItemInfo.reservedItemsDict;
				syncReservedItemsList = ReservedItemInfo.reservedItemsList;
				syncReservedItemSlotReps = ReservedItemInfo.reservedItemSlotReps;
			}
			else
			{
				syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();
				syncReservedItemsList = new List<ReservedItemInfo>();
				syncReservedItemSlotReps = new List<ReservedItemInfo>();
			}
			RequestSyncWithServer();
		}

		private static void RequestSyncWithServer()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Requesting sync with server.");
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-RequestSyncServerRpc", 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)3);
			}
		}

		private static void RequestSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			Plugin.Log("Receiving sync request from client: " + clientId);
			int num = 4 * syncReservedItemsList.Count;
			foreach (ReservedItemInfo syncReservedItems in syncReservedItemsList)
			{
				num += 4 + 2 * syncReservedItems.itemName.Length;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, -1);
			int count = syncReservedItemsList.Count;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
			foreach (ReservedItemInfo syncReservedItems2 in syncReservedItemsList)
			{
				count = syncReservedItems2.itemName.Length;
				((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
				string itemName = syncReservedItems2.itemName;
				for (int i = 0; i < itemName.Length; i++)
				{
					char c = itemName[i];
					((FastBufferWriter)(ref val)).WriteValue<char>(ref c, default(ForPrimitives));
				}
				((FastBufferWriter)(ref val)).WriteValue<int>(ref syncReservedItems2.hotbarSlotPriority, default(ForPrimitives));
			}
			Plugin.Log("Sent sync to client.");
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-RequestSyncClientRpc", clientId, val, (NetworkDelivery)3);
		}

		private static void RequestSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
			{
				return;
			}
			PlayerPatcher.isSynced = false;
			isSynced = true;
			syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();
			syncReservedItemsList = new List<ReservedItemInfo>();
			syncReservedItemSlotReps = new List<ReservedItemInfo>();
			Plugin.Log("Receiving sync from server.");
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			char c = default(char);
			for (int i = 0; i < num; i++)
			{
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
				((FastBufferReader)(ref reader)).TryBeginRead(2 * num2);
				string text = "";
				for (int j = 0; j < num2; j++)
				{
					((FastBufferReader)(ref reader)).ReadValue<char>(ref c, default(ForPrimitives));
					text += c;
				}
				bool flag = ReservedItemInfo.reservedItemsDict.ContainsKey(text);
				ReservedItemInfo reservedItemInfo = (ReservedItemInfo.reservedItemsDict.ContainsKey(text) ? ReservedItemInfo.reservedItemsDict[text] : new ReservedItemInfo
				{
					itemName = text
				});
				((FastBufferReader)(ref reader)).ReadValue<int>(ref reservedItemInfo.hotbarSlotPriority, default(ForPrimitives));
				Plugin.Log("Receiving sync for item: - Item: " + reservedItemInfo.itemName + " Prio: " + reservedItemInfo.hotbarSlotPriority);
				ReservedItemInfo.AddItemInfoToList(reservedItemInfo, syncReservedItemsList, syncReservedItemsDict, syncReservedItemSlotReps);
			}
			Plugin.Log("Received sync for " + syncReservedItemSlotReps.Count + " reserved item slots. (" + syncReservedItemsList.Count + " items total)");
		}

		private static void SendSwapHotbarUpdate(int hotbarSlot)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Sending OnSwapReservedHotbar update to server. Hotbar slot: " + hotbarSlot);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValue<int>(ref hotbarSlot, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-OnSwapHotbarServerRpc", 0uL, val, (NetworkDelivery)3);
			}
		}

		private static void OnSwapHotbarServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			if (NetworkManager.Singleton.IsServer)
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
				Plugin.Log("Receiving OnSwapReservedHotbar update from client. ClientId: " + clientId + " Slot: " + num);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref clientId, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("ReservedItemSlots-OnSwapHotbarClientRpc", val, (NetworkDelivery)3);
			}
		}

		private static void OnSwapHotbarClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				int hotbarSlot = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref hotbarSlot, default(ForPrimitives));
				ulong num = default(ulong);
				((FastBufferReader)(ref reader)).ReadValue<ulong>(ref num, default(ForPrimitives));
				Plugin.Log("Receiving OnSwapReservedHotbar update from client. ClientId: " + num + " Slot: " + hotbarSlot);
				if (num != localPlayerController.actualClientId && !TryUpdateClientHotbarSlot(num, hotbarSlot))
				{
					Plugin.Log("Failed to receive hotbar swap index from Client: " + num);
				}
			}
		}

		private static bool TryUpdateClientHotbarSlot(ulong clientId, int hotbarSlot)
		{
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if (val.actualClientId == clientId)
				{
					CallSwitchToItemSlotMethod(val, hotbarSlot);
					return true;
				}
			}
			return false;
		}

		public static void SwapHotbarSlot(int hotbarIndex)
		{
			SendSwapHotbarUpdate(hotbarIndex);
			CallSwitchToItemSlotMethod(localPlayerController, hotbarIndex);
		}

		private static void CallSwitchToItemSlotMethod(PlayerControllerB playerController, int hotbarIndex)
		{
			if (!((Object)(object)playerController == (Object)null) && playerController.ItemSlots != null && hotbarIndex >= 0 && hotbarIndex < playerController.ItemSlots.Length)
			{
				if ((Object)(object)playerController == (Object)(object)localPlayerController)
				{
					ShipBuildModeManager.Instance.CancelBuildMode(true);
					playerController.playerBodyAnimator.SetBool("GrabValidated", false);
				}
				ReservedItemPatcher.SwitchToItemSlot(playerController, hotbarIndex);
				if ((Object)(object)playerController.currentlyHeldObjectServer != (Object)null)
				{
					((Component)playerController.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(playerController.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f);
				}
			}
		}
	}
}
namespace ReservedItemSlotCore.Input
{
	internal class InputUtilsCompat
	{
		internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils");

		internal static InputActionAsset Asset => IngameKeybinds.GetAsset();

		public static InputAction FocusReservedHotbarHotkey => IngameKeybinds.Instance.FocusReservedHotbarHotkey;
	}
	internal class IngameKeybinds : LcInputActions
	{
		internal static IngameKeybinds Instance = new IngameKeybinds();

		[InputAction("<Keyboard>/leftAlt", Name = "[ReservedItemSlots]\nSwap hotbar")]
		public InputAction FocusReservedHotbarHotkey { get; set; }

		internal static InputActionAsset GetAsset()
		{
			return ((LcInputActions)Instance).Asset;
		}
	}
	[HarmonyPatch]
	internal class Keybinds
	{
		public static InputActionAsset Asset;

		public static InputActionMap ActionMap;

		public static InputAction FocusReservedHotbarAction;

		public static InputAction RawScrollAction;

		public static bool holdingModifierKey;

		public static bool scrollingReservedHotbar;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void AddToKeybindMenu()
		{
			InitKeybinds();
		}

		public static void InitKeybinds()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			if (InputUtilsCompat.Enabled)
			{
				Asset = InputUtilsCompat.Asset;
				FocusReservedHotbarAction = InputUtilsCompat.FocusReservedHotbarHotkey;
			}
			else
			{
				Asset = ScriptableObject.CreateInstance<InputActionAsset>();
				ActionMap = new InputActionMap("ReservedItemSlots");
				InputActionSetupExtensions.AddActionMap(Asset, ActionMap);
				FocusReservedHotbarAction = InputActionSetupExtensions.AddAction(ActionMap, "ReservedItemSlots.FocusReservedHotbar", (InputActionType)0, ConfigSettings.focusReservedHotbarHotkey.Value, (string)null, (string)null, (string)null, (string)null);
			}
			RawScrollAction = new InputAction("ReservedItemSlots.RawScroll", (InputActionType)0, "<Mouse>/scroll/y", (string)null, (string)null, (string)null);
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPrefix]
		public static void OnEnable()
		{
			Asset.Enable();
			RawScrollAction.Enable();
			FocusReservedHotbarAction.performed += FocusReservedHotbarSlotsAction;
			if (!ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				FocusReservedHotbarAction.canceled += UnfocusReservedHotbarSlotsPerformed;
			}
			RawScrollAction.performed += OnScrollReservedHotbar;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPrefix]
		public static void OnDisable()
		{
			Asset.Disable();
			RawScrollAction.Disable();
			FocusReservedHotbarAction.performed -= FocusReservedHotbarSlotsAction;
			if (!ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				FocusReservedHotbarAction.canceled -= UnfocusReservedHotbarSlotsPerformed;
			}
			RawScrollAction.performed -= OnScrollReservedHotbar;
		}

		private static void FocusReservedHotbarSlotsAction(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !((NetworkBehaviour)localPlayerController).IsOwner || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject) || SyncManager.numReservedItemSlots <= 0 || !HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return;
			}
			if (!ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				holdingModifierKey = true;
			}
			if (((CallbackContext)(ref context)).performed && ReservedItemPatcher.CanSwapToReservedHotbarSlot())
			{
				if (!ConfigSettings.toggleFocusReservedHotbar.Value)
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(active: true);
				}
				else
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(!PlayerPatcher.playerDataLocal.currentItemSlotIsReserved);
				}
			}
		}

		private static void UnfocusReservedHotbarSlotsPerformed(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((NetworkBehaviour)localPlayerController).IsOwner && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
			{
				holdingModifierKey = false;
				if (((CallbackContext)(ref context)).canceled && ReservedItemPatcher.CanSwapToReservedHotbarSlot())
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(active: false);
				}
			}
		}

		private static void OnScrollReservedHotbar(CallbackContext context)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localPlayerController == (Object)null) && ((NetworkBehaviour)localPlayerController).IsOwner && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject) && ((CallbackContext)(ref context)).performed && !PlayerPatcher.playerDataLocal.throwingObject && !scrollingReservedHotbar && PlayerPatcher.playerDataLocal.currentItemSlotIsReserved && PlayerPatcher.playerDataLocal.grabbingReservedItemInfo == null)
			{
				scrollingReservedHotbar = true;
				MethodInfo method = ((object)localPlayerController).GetType().GetMethod("ScrollMouse_performed", BindingFlags.Instance | BindingFlags.NonPublic);
				method.Invoke(localPlayerController, new object[1] { context });
				((MonoBehaviour)localPlayerController).StartCoroutine(ResetScrollDelayed());
			}
			static IEnumerator ResetScrollDelayed()
			{
				yield return null;
				yield return (object)new WaitForEndOfFrame();
				scrollingReservedHotbar = false;
			}
		}
	}
}
namespace ReservedItemSlotCore.Patches
{
	[HarmonyPatch]
	public static class HUDPatcher
	{
		private static bool usingController;

		private static float iconWidth;

		private static float xPos;

		private static TextMeshProUGUI hotkeyTooltip;

		public static List<Image> reservedItemSlots;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static bool localPlayerUsingController => (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.localPlayerUsingController;

		public static bool hasReservedItemSlotsAndEnabled => reservedItemSlots != null && reservedItemSlots.Count > 0 && ((Component)reservedItemSlots[0]).gameObject.activeSelf && ((Behaviour)reservedItemSlots[0]).enabled;

		[HarmonyPatch(typeof(HUDManager), "Awake")]
		[HarmonyPostfix]
		public static void Initialize(HUDManager __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			CanvasScaler componentInParent = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<CanvasScaler>();
			AspectRatioFitter componentInParent2 = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<AspectRatioFitter>();
			iconWidth = ((Component)__instance.itemSlotIconFrames[0]).GetComponent<RectTransform>().sizeDelta.x;
			xPos = componentInParent.referenceResolution.x / 2f / componentInParent2.aspectRatio - iconWidth / 4f;
			reservedItemSlots = new List<Image>();
		}

		[HarmonyPatch(typeof(StartOfRound), "Update")]
		[HarmonyPostfix]
		public static void UpdateUsingController(StartOfRound __instance)
		{
			if (!((Object)(object)__instance.localPlayerController == (Object)null) && !((Object)(object)hotkeyTooltip == (Object)null) && ((Component)hotkeyTooltip).gameObject.activeSelf && ((Behaviour)hotkeyTooltip).enabled && __instance.localPlayerUsingController != usingController)
			{
				usingController = __instance.localPlayerUsingController;
				UpdateHotkeyTooltipText();
			}
		}

		public static void AddNewHotbarSlotsHud()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerPatcher.reservedHotbarSize <= 0)
			{
				return;
			}
			List<Image> list = new List<Image>(HUDManager.Instance.itemSlotIconFrames);
			List<Image> list2 = new List<Image>(HUDManager.Instance.itemSlotIcons);
			float y = ((Component)HUDManager.Instance.itemSlotIconFrames[0]).GetComponent<RectTransform>().sizeDelta.y;
			Vector3 eulerAngles = ((Transform)((Component)HUDManager.Instance.itemSlotIconFrames[0]).GetComponent<RectTransform>()).eulerAngles;
			Vector3 eulerAngles2 = ((Transform)((Component)HUDManager.Instance.itemSlotIcons[0]).GetComponent<RectTransform>()).eulerAngles;
			Plugin.Log($"Adding {SyncManager.syncReservedItemSlotReps.Count} reserved item slots to the inventory HUD. Previous inventory HUD size: {PlayerPatcher.playerDataLocal.reservedHotbarStartIndex}");
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < SyncManager.syncReservedItemSlotReps.Count; i++)
			{
				ReservedItemInfo reservedItemInfo = SyncManager.syncReservedItemSlotReps[i];
				Plugin.Log($"Adding Reserved item slot for item types [{reservedItemInfo.itemName}]. Inventory index: {list.Count}");
				float num3 = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + 1.125f * y * (float)((reservedItemInfo.hotbarSlotPriority >= 0) ? num : num2);
				Image val = Object.Instantiate<Image>(HUDManager.Instance.itemSlotIconFrames[0], ((Component)HUDManager.Instance.itemSlotIconFrames[0]).transform.parent);
				((Object)val).name = "Slot" + list.Count + " [ReservedItemSlot]";
				((Graphic)val).rectTransform.anchoredPosition = new Vector2((reservedItemInfo.hotbarSlotPriority >= 0) ? xPos : (0f - xPos), num3);
				((Transform)((Graphic)val).rectTransform).eulerAngles = eulerAngles;
				CanvasGroup val2 = ((Component)val).gameObject.AddComponent<CanvasGroup>();
				val2.ignoreParentGroups = ConfigSettings.preventReservedItemSlotFade.Value;
				val2.alpha = 1f;
				Image component = ((Component)((Component)val).transform.GetChild(0)).GetComponent<Image>();
				((Object)component).name = "Icon";
				((Transform)((Graphic)component).rectTransform).eulerAngles = eulerAngles2;
				reservedItemSlots.Add(val);
				list.Insert(PlayerPatcher.playerDataLocal.reservedHotbarStartIndex + i, val);
				list2.Insert(PlayerPatcher.playerDataLocal.reservedHotbarStartIndex + i, component);
				if (reservedItemInfo.hotbarSlotPriority >= 0)
				{
					num++;
				}
				else
				{
					num2++;
				}
			}
			if (SyncManager.numReservedItemSlots > 0)
			{
				if ((Object)(object)hotkeyTooltip == (Object)null)
				{
					hotkeyTooltip = new GameObject("ReservedItemSlotTooltip", new Type[2]
					{
						typeof(RectTransform),
						typeof(TextMeshProUGUI)
					}).GetComponent<TextMeshProUGUI>();
				}
				RectTransform rectTransform = ((TMP_Text)hotkeyTooltip).rectTransform;
				((Component)rectTransform).transform.parent = ((Component)reservedItemSlots[0]).transform;
				((Transform)rectTransform).localScale = Vector3.one;
				rectTransform.sizeDelta = new Vector2(((Graphic)list[0]).rectTransform.sizeDelta.x * 2f, 10f);
				rectTransform.pivot = Vector2.one / 2f;
				rectTransform.anchoredPosition3D = new Vector3(0f, (0f - rectTransform.sizeDelta.x / 2f) * 1.2f, 0f);
				((TMP_Text)hotkeyTooltip).font = ((TMP_Text)HUDManager.Instance.controlTipLines[0]).font;
				((TMP_Text)hotkeyTooltip).fontSize = 7f;
				((TMP_Text)hotkeyTooltip).alignment = (TextAlignmentOptions)514;
				UpdateHotkeyTooltipText();
			}
			HUDManager.Instance.itemSlotIconFrames = list.ToArray();
			HUDManager.Instance.itemSlotIcons = list2.ToArray();
			Plugin.Log($"Finished adding {PlayerPatcher.reservedHotbarSize} Reserved Item slots in the inventory HUD.");
		}

		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		[HarmonyPostfix]
		public static void UpdateHotkeyTextOnMenuClosed(QuickMenuManager __instance)
		{
			if (!__instance.isMenuOpen)
			{
				UpdateHotkeyTooltipText();
			}
		}

		private static void UpdateHotkeyTooltipText()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localPlayerController == (Object)null) && !((Object)(object)hotkeyTooltip == (Object)null) && Keybinds.FocusReservedHotbarAction != null)
			{
				int num = (localPlayerUsingController ? 1 : 0);
				InputBinding val;
				string key;
				if (!InputUtilsCompat.Enabled)
				{
					val = Keybinds.FocusReservedHotbarAction.bindings[num];
					key = ((InputBinding)(ref val)).overridePath;
				}
				else
				{
					val = Keybinds.FocusReservedHotbarAction.bindings[num];
					key = ((InputBinding)(ref val)).path;
				}
				string displayName = ConfigSettings.GetDisplayName(key);
				TextMeshProUGUI obj = hotkeyTooltip;
				string text3;
				if (!ConfigSettings.toggleFocusReservedHotbar.Value)
				{
					string text2 = (((TMP_Text)hotkeyTooltip).text = string.Format($"Hold: [{displayName}]"));
					text3 = text2;
				}
				else
				{
					text3 = string.Format($"Toggle: [{displayName}]");
				}
				((TMP_Text)obj).text = text3;
			}
		}

		public static void UpdateHUD()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (AdvancedCompanyPatcher.Enabled)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < PlayerPatcher.reservedHotbarSize; i++)
			{
				ReservedItemInfo reservedItemInfo = SyncManager.syncReservedItemSlotReps[i];
				int num3 = PlayerPatcher.playerDataLocal.reservedHotbarStartIndex + i;
				float num4 = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + 1.125f * iconWidth * (float)((reservedItemInfo.hotbarSlotPriority >= 0) ? num : num2);
				((Graphic)HUDManager.Instance.itemSlotIconFrames[num3]).rectTransform.anchoredPosition = new Vector2((reservedItemInfo.hotbarSlotPriority >= 0) ? xPos : (0f - xPos), num4);
				if (reservedItemInfo.hotbarSlotPriority >= 0)
				{
					num++;
				}
				else
				{
					num2++;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class MouseScrollPatcher
	{
		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PlayerControllerB), "NextItemSlot")]
		[HarmonyPrefix]
		public static void CorrectReservedScrollDirectionNextItemSlot(ref bool forward)
		{
			if (Keybinds.scrollingReservedHotbar)
			{
				forward = Keybinds.RawScrollAction.ReadValue<float>() > 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchItemSlotsServerRpc")]
		[HarmonyPrefix]
		public static void CorrectReservedScrollDirectionServerRpc(ref bool forward)
		{
			if (Keybinds.scrollingReservedHotbar)
			{
				forward = Keybinds.RawScrollAction.ReadValue<float>() > 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool PreventInvertedScrollingReservedHotbar(CallbackContext context)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.localPlayerUsingController || SyncManager.numReservedItemSlots <= 0)
			{
				return true;
			}
			if (PlayerPatcher.playerDataLocal.currentItemSlotIsReserved)
			{
				if (!HUDPatcher.hasReservedItemSlotsAndEnabled)
				{
					return true;
				}
				if (HUDPatcher.reservedItemSlots.Count >= 2 && ((Graphic)HUDPatcher.reservedItemSlots[1]).rectTransform.anchoredPosition.y - ((Graphic)HUDPatcher.reservedItemSlots[0]).rectTransform.anchoredPosition.y <= 5f)
				{
					return true;
				}
				if (!Keybinds.scrollingReservedHotbar || SyncManager.numReservedItemSlots == 1 || (PlayerPatcher.playerDataLocal.GetNumHeldReservedItems() == 1 && (Object)(object)localPlayerController.ItemSlots[localPlayerController.currentItemSlot] != (Object)null))
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class ReservedItemPatcher
	{
		public static int indexInHotbar;

		public static int indexInReservedHotbar;

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static int reservedHotbarSize => SyncManager.numReservedItemSlots;

		private static GrabbableObject GetCurrentlyGrabbingObject(PlayerControllerB playerController)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (GrabbableObject)Traverse.Create((object)playerController).Field("currentlyGrabbingObject").GetValue();
		}

		private static void SetCurrentlyGrabbingObject(PlayerControllerB playerController, GrabbableObject grabbable)
		{
			Traverse.Create((object)playerController).Field("currentlyGrabbingObject").SetValue((object)grabbable);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPrefix]
		public static bool GrabReservedItemPrefix(PlayerControllerB __instance)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if ((!SyncManager.isSynced && !SyncManager.canUseModDisabledOnHost) || !HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return true;
			}
			PlayerPatcher.playerDataLocal.grabbingReservedItemInfo = null;
			PlayerPatcher.playerDataLocal.grabbingReservedItem = null;
			PlayerPatcher.playerDataLocal.previousHotbarIndex = -1;
			if (PlayerPatcher.playerDataLocal.currentItemSlotIsReserved && !ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				return false;
			}
			if (__instance.twoHanded || __instance.sinkingValue > 0.73f)
			{
				return true;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, __instance.grabDistance, PlayerPatcher.INTERACTABLE_OBJECT_MASK) && ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer != 8 && ((Component)((RaycastHit)(ref val2)).collider).tag == "PhysicsProp")
			{
				GrabbableObject component = ((Component)((Component)((RaycastHit)(ref val2)).collider).transform).gameObject.GetComponent<GrabbableObject>();
				if ((Object)(object)component != (Object)null && !__instance.inSpecialInteractAnimation && !component.isHeld && !component.isPocketed)
				{
					NetworkObject networkObject = ((NetworkBehaviour)component).NetworkObject;
					if ((Object)(object)networkObject != (Object)null && networkObject.IsSpawned && SyncManager.TryGetReservedItemInfo(component, out var info))
					{
						Plugin.Log("Beginning grab on reserved item: " + info.itemName);
						PlayerPatcher.playerDataLocal.grabbingReservedItemInfo = info;
						PlayerPatcher.playerDataLocal.grabbingReservedItem = component;
						PlayerPatcher.playerDataLocal.previousHotbarIndex = __instance.currentItemSlot;
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPostfix]
		public static void GrabReservedItemPostfix(PlayerControllerB __instance)
		{
			if (PlayerPatcher.playerDataLocal.grabbingReservedItemInfo != null)
			{
				SetSpecialGrabAnimationBool(__instance, setTrue: false);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPrefix]
		public static void GrabReservedItemClientRpcPrefix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if ((!SyncManager.isSynced && !SyncManager.canUseModDisabledOnHost) || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance))
			{
				return;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
			NetworkObject val = default(NetworkObject);
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening && grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
			{
				GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>();
				if (SyncManager.TryGetReservedItemInfo(component, out var info))
				{
					if (IsItemSlotEmpty(info, __instance))
					{
						Plugin.Log("OnGrabReservedItem for Player: " + ((Object)__instance).name + " Item: " + info.itemName);
						reservedPlayerData.grabbingReservedItemInfo = info;
						reservedPlayerData.grabbingReservedItem = component;
						reservedPlayerData.previousHotbarIndex = __instance.currentItemSlot;
						return;
					}
					Plugin.LogWarning("OnGrabReservedItem SlotFilled. Player: " + ((Object)__instance).name + " Item: " + info.itemName + " Slot: " + (reservedPlayerData.reservedHotbarStartIndex + info.reservedItemIndex));
				}
			}
			reservedPlayerData.grabbingReservedItemInfo = null;
			reservedPlayerData.grabbingReservedItem = null;
			reservedPlayerData.previousHotbarIndex = -1;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPostfix]
		public static void GrabReservedItemClientRpcPostfix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			//IL_00c0: 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)
			//IL_0197: 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)
			if ((!SyncManager.isSynced && SyncManager.canUseModDisabledOnHost) || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance))
			{
				return;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
			if (reservedPlayerData.grabbingReservedItemInfo == null)
			{
				return;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening)
			{
				NetworkObject val = default(NetworkObject);
				if (grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
				{
					GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>();
					if (SyncManager.TryGetReservedItemInfo(component, out var info))
					{
						SetSpecialGrabAnimationBool(__instance, (Object)(object)reservedPlayerData.previouslyHeldItem != (Object)null, reservedPlayerData.previouslyHeldItem);
						Animator playerBodyAnimator = __instance.playerBodyAnimator;
						AnimatorStateInfo currentAnimatorStateInfo = __instance.playerBodyAnimator.GetCurrentAnimatorStateInfo(2);
						playerBodyAnimator.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash, 2, 1f);
						if ((Object)(object)reservedPlayerData.previouslyHeldItem != (Object)null)
						{
							reservedPlayerData.previouslyHeldItem.EnableItemMeshes(true);
						}
						ForceDisableItemMesh(reservedPlayerData.grabbingReservedItem);
						Traverse.Create((object)component).Field("previousPlayerHeldBy").SetValue((object)__instance);
						if ((Object)(object)__instance != (Object)(object)localPlayerController)
						{
							Plugin.Log("OnGrabReservedItem completed. Player: " + ((Object)__instance).name + " Item: " + info.itemName + " Switching to previous slot: " + reservedPlayerData.previousHotbarIndex);
							SwitchToItemSlot(__instance, reservedPlayerData.previousHotbarIndex);
							Animator playerBodyAnimator2 = __instance.playerBodyAnimator;
							currentAnimatorStateInfo = __instance.playerBodyAnimator.GetCurrentAnimatorStateInfo(2);
							playerBodyAnimator2.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash, 2, 1f);
							reservedPlayerData.grabbingReservedItemInfo = null;
							reservedPlayerData.grabbingReservedItem = null;
							reservedPlayerData.previousHotbarIndex = -1;
						}
						else
						{
							int num = reservedPlayerData.reservedHotbarStartIndex + reservedPlayerData.grabbingReservedItemInfo.reservedItemIndex;
							((Component)HUDManager.Instance.itemSlotIconFrames[num]).GetComponent<Animator>().SetBool("selectedSlot", false);
							((Component)HUDManager.Instance.itemSlotIconFrames[reservedPlayerData.previousHotbarIndex]).GetComponent<Animator>().SetBool("selectedSlot", true);
							((Component)HUDManager.Instance.itemSlotIconFrames[num]).GetComponent<Animator>().Play("PanelLines", 0, 1f);
							((Component)HUDManager.Instance.itemSlotIconFrames[reservedPlayerData.previousHotbarIndex]).GetComponent<Animator>().Play("PanelEnlarge", 0, 1f);
						}
						return;
					}
				}
				else if ((Object)(object)__instance == (Object)(object)localPlayerController)
				{
					Plugin.Log("Failed to validate ReservedItemGrab by the local player. Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ".");
					Traverse.Create((object)localPlayerController).Field("grabInvalidated").SetValue((object)true);
				}
				else
				{
					Plugin.Log("Failed to validate ReservedItemGrab by player with id: " + ((Object)__instance).name + ". Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ".");
				}
			}
			reservedPlayerData.grabbingReservedItemInfo = null;
			reservedPlayerData.grabbingReservedItem = null;
			reservedPlayerData.previousHotbarIndex = -1;
		}

		[HarmonyPatch(typeof(GrabbableObject), "GrabItemOnClient")]
		[HarmonyPrefix]
		public static void OnReservedItemGrabbed(GrabbableObject __instance)
		{
			if (PlayerPatcher.playerDataLocal.grabbingReservedItemInfo != null && !((Object)(object)__instance != (Object)(object)GetCurrentlyGrabbingObject(localPlayerController)))
			{
				((MonoBehaviour)localPlayerController).StartCoroutine(OnReservedItemGrabbedEndOfFrame());
			}
			IEnumerator OnReservedItemGrabbedEndOfFrame()
			{
				yield return (object)new WaitForEndOfFrame();
				SwitchToItemSlot(localPlayerController, PlayerPatcher.playerDataLocal.previousHotbarIndex);
				PlayerPatcher.playerDataLocal.grabbingReservedItemInfo = null;
				PlayerPatcher.playerDataLocal.grabbingReservedItem = null;
				PlayerPatcher.playerDataLocal.previousHotbarIndex = -1;
				__instance.EnableItemMeshes(false);
				__instance.PocketItem();
				Animator playerBodyAnimator = localPlayerController.playerBodyAnimator;
				AnimatorStateInfo currentAnimatorStateInfo = localPlayerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(2);
				playerBodyAnimator.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash, 2, 1f);
			}
		}

		[HarmonyPatch(typeof(HUDManager), "ClearControlTips")]
		[HarmonyPrefix]
		public static bool PreventClearControlTipsGrabbingReservedItem(HUDManager __instance)
		{
			return PlayerPatcher.playerDataLocal == null || (Object)(object)PlayerPatcher.playerDataLocal.grabbingReservedItem == (Object)null;
		}

		[HarmonyPatch(typeof(GrabbableObject), "SetControlTipsForItem")]
		[HarmonyPrefix]
		public static bool PreventUpdateControlTipsGrabbingReservedItem(GrabbableObject __instance)
		{
			return PlayerPatcher.playerDataLocal == null || (Object)(object)PlayerPatcher.playerDataLocal.grabbingReservedItem != (Object)(object)__instance;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SetSpecialGrabAnimationBool")]
		[HarmonyPrefix]
		public static bool PreventSpecialGrabAnimationReservedItem(bool setTrue, PlayerControllerB __instance, GrabbableObject currentItem = null)
		{
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
		[HarmonyPrefix]
		public static void DebugSwitchToItemSlot(int slot, PlayerControllerB __instance)
		{
			if (!HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
			if (reservedPlayerData == null)
			{
				Plugin.LogError("PlayerData null for player: " + ((Object)__instance).name);
			}
			else
			{
				if (!reservedPlayerData.IsReservedItemSlot(slot))
				{
					return;
				}
				string text = "";
				reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
				if (slot < 0)
				{
					text = "Called SwitchToItemSlot on slot: " + slot;
				}
				else if (slot >= __instance.ItemSlots.Length)
				{
					text = "Called SwitchToItemSlot on slot: " + slot + " HotbarSize: " + __instance.ItemSlots.Length;
				}
				else
				{
					if (slot < HUDManager.Instance.itemSlotIconFrames.Length)
					{
						return;
					}
					text = "Called SwitchToItemSlot on slot: " + slot + " NumItemSlotsHUD: " + HUDManager.Instance.itemSlotIconFrames.Length;
				}
				text += "\n\n";
				text = text + reservedPlayerData.DumpData() + "\n\nReporting this error to Flip would be greatly appreciated!";
				Debug.LogError((object)text);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
		[HarmonyPostfix]
		public static void UpdateFocusReservedHotbar(int slot, PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && PlayerPatcher.allPlayerData.TryGetValue(__instance, out var value))
			{
				value.inReservedHotbarSlots = value.IsReservedItemSlot(__instance.currentItemSlot);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "FirstEmptyItemSlot")]
		[HarmonyPostfix]
		public static void GetReservedItemSlotPlacementIndex(ref int __result, PlayerControllerB __instance)
		{
			if (reservedHotbarSize <= 0 || !HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
			ReservedItemInfo grabbingReservedItemInfo = reservedPlayerData.grabbingReservedItemInfo;
			if (grabbingReservedItemInfo != null)
			{
				if (IsItemSlotEmpty(grabbingReservedItemInfo, __instance))
				{
					__result = reservedPlayerData.reservedHotbarStartIndex + grabbingReservedItemInfo.reservedItemIndex;
					return;
				}
				reservedPlayerData.grabbingReservedItemInfo = null;
				reservedPlayerData.grabbingReservedItem = null;
				reservedPlayerData.previousHotbarIndex = -1;
			}
			if (!reservedPlayerData.IsReservedItemSlot(__result))
			{
				return;
			}
			__result = -1;
			for (int i = 0; i < __instance.ItemSlots.Length; i++)
			{
				if (!reservedPlayerData.IsReservedItemSlot(i) && (Object)(object)__instance.ItemSlots[i] == (Object)null)
				{
					__result = i;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "NextItemSlot")]
		[HarmonyPostfix]
		public static void OnNextItemSlot(ref int __result, bool forward, PlayerControllerB __instance)
		{
			if (reservedHotbarSize <= 0 || !HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[__instance];
			bool flag = reservedPlayerData.IsReservedItemSlot(__result);
			if (flag == reservedPlayerData.inReservedHotbarSlots && (!flag || (Object)(object)__instance.ItemSlots[__result] != (Object)null))
			{
				return;
			}
			int num = (forward ? 1 : (-1));
			__result = __instance.currentItemSlot + num;
			__result = ((__result < 0) ? (__instance.ItemSlots.Length - 1) : ((__result < __instance.ItemSlots.Length) ? __result : 0));
			bool flag2 = reservedPlayerData.IsReservedItemSlot(__result);
			if (!reservedPlayerData.inReservedHotbarSlots)
			{
				if (flag2)
				{
					__result = (forward ? ((reservedPlayerData.reservedHotbarStartIndex + reservedHotbarSize) % __instance.ItemSlots.Length) : (reservedPlayerData.reservedHotbarStartIndex - 1));
				}
				return;
			}
			__result = (flag2 ? __result : (forward ? reservedPlayerData.reservedHotbarStartIndex : (reservedPlayerData.reservedHotbarStartIndex + reservedHotbarSize - 1)));
			int numHeldReservedItems = reservedPlayerData.GetNumHeldReservedItems();
			while (numHeldReservedItems > 0 && __result != reservedPlayerData.currentItemSlot && (Object)(object)__instance.ItemSlots[__result] == (Object)null)
			{
				__result += num;
				__result = ((!reservedPlayerData.IsReservedItemSlot(__result)) ? (forward ? reservedPlayerData.reservedHotbarStartIndex : (reservedPlayerData.reservedHotbarStartIndex + reservedHotbarSize - 1)) : __result);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPrefix]
		public static void RefocusReservedHotbarAfterAnimation(PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && !((Object)(object)__instance != (Object)(object)localPlayerController) && !ConfigSettings.toggleFocusReservedHotbar.Value && Keybinds.holdingModifierKey != PlayerPatcher.playerDataLocal.currentItemSlotIsReserved && CanSwapToReservedHotbarSlot())
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}

		public static bool CanSwapToReservedHotbarSlot()
		{
			if (!HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return false;
			}
			bool flag = (bool)Traverse.Create((object)localPlayerController).Field("throwingObject").GetValue();
			return !(PlayerPatcher.playerDataLocal.grabbingReservedItemInfo != null || localPlayerController.isGrabbingObjectAnimation || localPlayerController.quickMenuManager.isMenuOpen || localPlayerController.inSpecialInteractAnimation || flag) && !localPlayerController.isTypingChat && !localPlayerController.twoHanded && !localPlayerController.activatingItem && !localPlayerController.jetpackControls && !localPlayerController.disablingJetpackControls && !localPlayerController.inTerminalMenu && !localPlayerController.isPlayerDead && !(GetTimeSinceSwitchingSlots(localPlayerController) < 0.3f);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "UpdateSpecialAnimationValue")]
		[HarmonyPostfix]
		public static void OnSpecialAnimationUpdate(bool specialAnimation, PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && !((Object)(object)__instance != (Object)(object)localPlayerController) && !specialAnimation && !ConfigSettings.toggleFocusReservedHotbar.Value && PlayerPatcher.playerDataLocal.currentItemSlotIsReserved != Keybinds.holdingModifierKey)
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}

		public static void FocusReservedHotbarSlots(bool active)
		{
			if (!HUDPatcher.hasReservedItemSlotsAndEnabled || (reservedHotbarSize <= 0 && active) || PlayerPatcher.playerDataLocal.currentItemSlotIsReserved == active)
			{
				return;
			}
			ReservedPlayerData playerDataLocal = PlayerPatcher.playerDataLocal;
			indexInHotbar = Mathf.Clamp(indexInHotbar, 0, localPlayerController.ItemSlots.Length - 1);
			indexInHotbar = ((!playerDataLocal.IsReservedItemSlot(indexInHotbar)) ? indexInHotbar : 0);
			indexInReservedHotbar = Mathf.Clamp(indexInReservedHotbar, playerDataLocal.reservedHotbarStartIndex, playerDataLocal.reservedHotbarEndIndexExcluded - 1);
			int num = Mathf.Clamp(localPlayerController.currentItemSlot, 0, localPlayerController.ItemSlots.Length);
			int i = num;
			bool flag = active;
			if (flag && !playerDataLocal.IsReservedItemSlot(num))
			{
				indexInHotbar = num;
				indexInHotbar = ((!playerDataLocal.IsReservedItemSlot(indexInHotbar)) ? indexInHotbar : 0);
				i = indexInReservedHotbar;
				if ((Object)(object)localPlayerController.ItemSlots[i] == (Object)null && playerDataLocal.GetNumHeldReservedItems() > 0)
				{
					for (i = playerDataLocal.reservedHotbarStartIndex; i < playerDataLocal.reservedHotbarEndIndexExcluded && !((Object)(object)localPlayerController.ItemSlots[i] != (Object)null); i++)
					{
					}
				}
				Plugin.Log("Focusing reserved hotbar slots. NewIndex: " + i + " OldIndex: " + num + " ReservedStartIndex: " + PlayerPatcher.playerDataLocal.reservedHotbarStartIndex);
			}
			else if (!flag && PlayerPatcher.playerDataLocal.IsReservedItemSlot(num))
			{
				indexInReservedHotbar = Mathf.Clamp(num, playerDataLocal.reservedHotbarStartIndex, playerDataLocal.reservedHotbarEndIndexExcluded - 1);
				i = indexInHotbar;
				Plugin.Log("Unfocusing reserved hotbar slots. NewIndex: " + i + " OldIndex: " + num + " ReservedStartIndex: " + PlayerPatcher.playerDataLocal.reservedHotbarStartIndex);
			}
			if (i < 0)
			{
				Plugin.LogError("Swapping to hotbar slot: " + i + ". Maybe send these logs to Flip? :)");
			}
			else if (i >= localPlayerController.ItemSlots.Length)
			{
				Plugin.LogError("Swapping to hotbar slot: " + i + " InventorySize: " + localPlayerController.ItemSlots.Length + ". Maybe send these logs to Flip? :)");
			}
			SyncManager.SwapHotbarSlot(i);
			if (localPlayerController.currentItemSlot != i)
			{
				Plugin.LogWarning("OnFocusReservedHotbarSlots - New hotbar index does not match target hotbar index. Tried to swap to index: " + i + " Current index: " + localPlayerController.currentItemSlot + " Tried swapping to reserved hotbar: " + active);
			}
		}

		internal static bool IsItemSlotEmpty(string itemName, PlayerControllerB playerController)
		{
			if (!SyncManager.TryGetReservedItemInfo(itemName, out var info))
			{
				return false;
			}
			return IsItemSlotEmpty(info, playerController);
		}

		internal static bool IsItemSlotEmpty(ReservedItemInfo itemInfo, PlayerControllerB playerController)
		{
			playerController = (((Object)(object)playerController == (Object)null) ? localPlayerController : playerController);
			if (reservedHotbarSize == 0)
			{
				return false;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[playerController];
			int num = reservedPlayerData.reservedHotbarStartIndex + itemInfo.reservedItemIndex;
			return num >= reservedPlayerData.reservedHotbarStartIndex && num < reservedPlayerData.reservedHotbarStartIndex + reservedHotbarSize && (Object)(object)playerController.ItemSlots[num] == (Object)null;
		}

		public static bool TryGetHeldReservedObject(string itemName, PlayerControllerB playerController, ref GrabbableObject obj)
		{
			playerController = (((Object)(object)playerController == (Object)null) ? localPlayerController : playerController);
			if ((Object)(object)playerController == (Object)null || reservedHotbarSize == 0)
			{
				return false;
			}
			if (!SyncManager.TryGetReservedItemInfo(itemName, out var info))
			{
				return false;
			}
			ReservedPlayerData reservedPlayerData = PlayerPatcher.allPlayerData[playerController];
			int num = reservedPlayerData.reservedHotbarStartIndex + info.reservedItemIndex;
			obj = playerController.ItemSlots[num];
			return (Object)(object)obj != (Object)null;
		}

		public static void ForceDisableItemMesh(GrabbableObject grabbableObject)
		{
			MeshRenderer[] componentsInChildren = ((Component)grabbableObject).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Renderer)val).enabled = false;
				}
			}
		}

		public static bool ReservedItemIsBeingGrabbed(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			foreach (ReservedPlayerData value in PlayerPatcher.allPlayerData.Values)
			{
				if ((Object)(object)grabbableObject == (Object)(object)value.grabbingReservedItem)
				{
					return true;
				}
			}
			return false;
		}

		public static float GetTimeSinceSwitchingSlots(PlayerControllerB playerController)
		{
			return (float)Traverse.Create((object)playerController).Field("timeSinceSwitchingSlots").GetValue();
		}

		public static void SetTimeSinceSwitchingSlots(PlayerControllerB playerController, float value)
		{
			Traverse.Create((object)playerController).Field("timeSinceSwitchingSlots").SetValue((object)value);
		}

		public static void SetSpecialGrabAnimationBool(PlayerControllerB playerController, bool setTrue, GrabbableObject currentItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SetSpecialGrabAnimationBool", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { setTrue, currentItem });
		}

		public static void SwitchToItemSlot(PlayerControllerB playerController, int slot, GrabbableObject fillSlotWithItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { slot, fillSlotWithItem });
			SetTimeSinceSwitchingSlots(playerController, 0f);
		}
	}
	[HarmonyPatch]
	public static class PlayerPatcher
	{
		public static PlayerControllerB localPlayerController;

		public static int vanillaHotbarSize = -1;

		public static int hotbarSizeBeforeSync = -1;

		internal static Dictionary<PlayerControllerB, ReservedPlayerData> allPlayerData = new Dictionary<PlayerControllerB, ReservedPlayerData>();

		public static bool spawned = false;

		public static bool isSynced = false;

		public static int INTERACTABLE_OBJECT_MASK { get; private set; }

		public static int reservedHotbarSize => SyncManager.numReservedItemSlots;

		internal static ReservedPlayerData playerDataLocal => (allPlayerData != null && (Object)(object)localPlayerController != (Object)null && allPlayerData.ContainsKey(localPlayerController)) ? allPlayerData[localPlayerController] : null;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void InitSession(StartOfRound __instance)
		{
			localPlayerController = null;
			vanillaHotbarSize = -1;
			ReservedItemPatcher.indexInHotbar = 0;
			ReservedItemPatcher.indexInReservedHotbar = -1;
			Keybinds.holdingModifierKey = false;
			allPlayerData.Clear();
			isSynced = false;
			spawned = false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
		[HarmonyPostfix]
		public static void InitializePlayerController(PlayerControllerB __instance)
		{
			if (vanillaHotbarSize == -1)
			{
				vanillaHotbarSize = __instance.ItemSlots.Length;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		public static void InitializePlayerControllerLate(PlayerControllerB __instance)
		{
			allPlayerData.Add(__instance, new ReservedPlayerData
			{
				playerController = __instance,
				hotbarSize = __instance.ItemSlots.Length,
				reservedHotbarStartIndex = __instance.ItemSlots.Length
			});
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void OnLocalPlayerConnect(PlayerControllerB __instance)
		{
			localPlayerController = __instance;
			INTERACTABLE_OBJECT_MASK = (int)Traverse.Create((object)__instance).Field("interactableObjectsMask").GetValue();
			((MonoBehaviour)__instance).StartCoroutine(UpdateHotbarSlotsAfterFirstSpawnAnimation());
		}

		private static IEnumerator UpdateHotbarSlotsAfterFirstSpawnAnimation()
		{
			yield return (object)new WaitForSeconds(3f);
			spawned = true;
			hotbarSizeBeforeSync = localPlayerController.ItemSlots.Length;
			if (!isSynced && (SyncManager.isSynced || SyncManager.canUseModDisabledOnHost))
			{
				OnSyncedWithServer();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPostfix]
		public static void OnUpdate(PlayerControllerB __instance)
		{
			if (!spawned)
			{
				return;
			}
			if (SyncManager.isSynced && !isSynced)
			{
				OnSyncedWithServer();
			}
			ReservedPlayerData reservedPlayerData = allPlayerData[__instance];
			if ((!isSynced && (!SyncManager.canUseModDisabledOnHost || (Object)(object)__instance != (Object)(object)localPlayerController)) || reservedHotbarSize <= 0 || reservedPlayerData.hotbarSize == __instance.ItemSlots.Length)
			{
				return;
			}
			Plugin.Log("On update inventory size for player: " + ((Object)__instance).name + " - Old hotbar size: " + reservedPlayerData.hotbarSize + " - New hotbar size: " + __instance.ItemSlots.Length);
			reservedPlayerData.hotbarSize = __instance.ItemSlots.Length;
			int num = -1;
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				if (HUDPatcher.reservedItemSlots != null && HUDPatcher.reservedItemSlots.Count > 0)
				{
					num = Array.IndexOf(HUDManager.Instance.itemSlotIconFrames, HUDPatcher.reservedItemSlots[0]);
					Plugin.Log("OnUpdateInventorySize A for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
				}
				if (num == -1)
				{
					for (int i = 0; i < HUDManager.Instance.itemSlotIconFrames.Length; i++)
					{
						if (((Object)HUDManager.Instance.itemSlotIconFrames[i]).name.ToLower().Contains("reserved"))
						{
							num = i;
							Plugin.Log("OnUpdateInventorySize B for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
							break;
						}
					}
				}
			}
			if (num == -1)
			{
				num = reservedPlayerData.reservedHotbarStartIndex;
				Plugin.Log("OnUpdateInventorySize C for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
			}
			if (num == -1)
			{
				num = vanillaHotbarSize;
				Plugin.Log("OnUpdateInventorySize D for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
			}
			reservedPlayerData.reservedHotbarStartIndex = num;
			if (reservedPlayerData.reservedHotbarStartIndex < 0)
			{
				Plugin.LogError("Set new reserved start index to slot: " + reservedPlayerData.reservedHotbarStartIndex + " . Maybe share these logs with Flip? :)");
			}
			if (reservedPlayerData.reservedHotbarEndIndexExcluded - 1 >= reservedPlayerData.playerController.ItemSlots.Length)
			{
				Plugin.LogError("Set new reserved start index to slot: " + reservedPlayerData.reservedHotbarStartIndex + " Last reserved slot index: " + (reservedPlayerData.reservedHotbarEndIndexExcluded - 1) + " Inventory size: " + reservedPlayerData.playerController.ItemSlots.Length + ". Maybe share these logs with Flip? :)");
			}
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				HUDPatcher.UpdateHUD();
			}
		}

		private static void OnSyncedWithServer()
		{
			isSynced = SyncManager.isSynced;
			int num = hotbarSizeBeforeSync + reservedHotbarSize;
			Plugin.Log("Finalizing sync with server. New hotbar size: " + num);
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				allPlayerData[val].reservedHotbarStartIndex = hotbarSizeBeforeSync;
				if (num != val.ItemSlots.Length)
				{
					Array.Resize(ref val.ItemSlots, num);
				}
				allPlayerData[val].hotbarSize = num;
			}
			if (HUDPatcher.reservedItemSlots != null && HUDPatcher.reservedItemSlots.Count == SyncManager.numReservedItemSlots && playerDataLocal.reservedHotbarStartIndex < HUDManager.Instance.itemSlotIconFrames.Length && (Object)(object)HUDPatcher.reservedItemSlots[0] == (Object)(object)HUDManager.Instance.itemSlotIconFrames[playerDataLocal.reservedHotbarStartIndex])
			{
				return;
			}
			if (HUDPatcher.reservedItemSlots != null && HUDPatcher.reservedItemSlots.Count > 0)
			{
				List<Image> list = new List<Image>(HUDManager.Instance.itemSlotIconFrames);
				List<Image> list2 = new List<Image>(HUDManager.Instance.itemSlotIcons);
				for (int j = 0; j < HUDManager.Instance.itemSlotIconFrames.Length; j++)
				{
					Image val2 = HUDManager.Instance.itemSlotIconFrames[j];
					Image item = HUDManager.Instance.itemSlotIcons[j];
					if (((Object)val2).name.Contains("Reserved"))
					{
						list.Remove(val2);
						list2.Remove(item);
					}
				}
				HUDManager.Instance.itemSlotIconFrames = list.ToArray();
				HUDManager.Instance.itemSlotIcons = list2.ToArray();
			}
			HUDPatcher.AddNewHotbarSlotsHud();
		}
	}
}
namespace ReservedItemSlotCore.Compatibility
{
	public class AdvancedCompanyPatcher
	{
		public static bool Enabled => Plugin.IsModLoaded("com.potatoepet.AdvancedCompany");
	}
}

mods/FlipMods-ReservedWalkieSlot-1.6.1/ReservedWalkieSlot.dll

Decompiled 10 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using ReservedWalkieSlot.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedWalkieSlot")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedWalkieSlot")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c15c320f-d8fc-4f1c-be3c-f2d2ffc41edd")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedWalkieSlot
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> activateWalkieKey;

		public static ConfigEntry<bool> hideWalkieMeshShoulder;

		public static string activateWalkieDisplayName;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			activateWalkieKey = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedWalkieSlot", "ActivateWalkieKey", "<Keyboard>/x", "This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)");
			hideWalkieMeshShoulder = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedWalkieSlot", "HideWalkieOnShoulder", false, "Hides the walkie mesh while on your shoulder. Only applies in scenarios where you can view your player in third person.");
			activateWalkieDisplayName = GetDisplayName(activateWalkieKey.Value);
			currentConfigEntries.Add(((ConfigEntryBase)activateWalkieKey).Definition.Key, (ConfigEntryBase)(object)activateWalkieKey);
			currentConfigEntries.Add(((ConfigEntryBase)hideWalkieMeshShoulder).Definition.Key, (ConfigEntryBase)(object)hideWalkieMeshShoulder);
			TryRemoveOldConfigSettings();
		}

		public static string GetDisplayName(string key)
		{
			key = key.Replace("<Keyboard>/", "");
			key = key.Replace("<Mouse>/", "");
			string text = key;
			text = text.Replace("leftAlt", "Alt");
			text = text.Replace("rightAlt", "Alt");
			text = text.Replace("leftCtrl", "Ctrl");
			text = text.Replace("rightCtrl", "Ctrl");
			text = text.Replace("leftShift", "Shift");
			text = text.Replace("rightShift", "Shift");
			text = text.Replace("leftButton", "LMB");
			text = text.Replace("rightButton", "RMB");
			return text.Replace("middleButton", "MMB");
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("FlipMods.ReservedWalkieSlot", "ReservedWalkieSlot", "1.6.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private Harmony _harmony;

		public static ReservedItemInfo walkieInfo = new ReservedItemInfo("Walkie-talkie", 100, true, true, true, true);

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("ReservedWalkieSlot");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ReservedWalkieSlot loaded");
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogWarning(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedWalkieSlot";

		public const string PLUGIN_NAME = "ReservedWalkieSlot";

		public const string PLUGIN_VERSION = "1.6.1";
	}
}
namespace ReservedWalkieSlot.Patches
{
	[HarmonyPatch]
	public class MaskedEnemyPatcher
	{
		public static Dictionary<MaskedPlayerEnemy, GameObject> heldWalkiesByEnemy = new Dictionary<MaskedPlayerEnemy, GameObject>();

		public static HashSet<MaskedPlayerEnemy> spawnedEnemies = new HashSet<MaskedPlayerEnemy>();

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "OnDestroy")]
		[HarmonyPrefix]
		public static void OnDestroy(MaskedPlayerEnemy __instance)
		{
			if (heldWalkiesByEnemy.TryGetValue(__instance, out var value))
			{
				Plugin.LogWarning("Destroying walkie. Enemy destroyed.");
				Object.DestroyImmediate((Object)(object)value);
				spawnedEnemies.Remove(__instance);
			}
			heldWalkiesByEnemy.Remove(__instance);
		}

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "LateUpdate")]
		[HarmonyPostfix]
		public static void ShowWalkieOnEnemy(MaskedPlayerEnemy __instance)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			if (!spawnedEnemies.Contains(__instance) && SyncManager.syncReservedItemsList.Contains(Plugin.walkieInfo) && !((EnemyAI)__instance).isEnemyDead && !heldWalkiesByEnemy.ContainsKey(__instance) && (Object)(object)__instance.mimickingPlayer != (Object)null && PlayerPatcher.allPlayerData.TryGetValue(__instance.mimickingPlayer, out var value))
			{
				spawnedEnemies.Add(__instance);
				WalkieTalkie reservedWalkie = WalkiePatcher.GetReservedWalkie(value.playerController);
				if ((Object)(object)reservedWalkie != (Object)null)
				{
					Plugin.LogWarning("OnMaskedEnemySpawn - MimickingPlayer: " + ((Object)value.playerController).name + " - Spawning walkie object on enemy.");
					GameObject val = new GameObject("ReservedWalkie [MaskedEnemy]");
					Light[] componentsInChildren = ((Component)reservedWalkie).GetComponentsInChildren<Light>();
					MeshRenderer mainObjectRenderer = ((GrabbableObject)reservedWalkie).mainObjectRenderer;
					Light[] array = componentsInChildren;
					foreach (Light val2 in array)
					{
						Light component = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.localPosition, ((Component)val2).transform.localRotation, val.transform).GetComponent<Light>();
						((Behaviour)component).enabled = true;
						((Component)component).gameObject.layer = 6;
					}
					MeshRenderer component2 = Object.Instantiate<GameObject>(((Component)mainObjectRenderer).gameObject, ((Component)mainObjectRenderer).transform.localPosition, ((Component)mainObjectRenderer).transform.localRotation, val.transform).GetComponent<MeshRenderer>();
					((Renderer)component2).enabled = true;
					((Component)component2).gameObject.layer = 6;
					val.transform.localScale = ((Component)reservedWalkie).transform.localScale;
					heldWalkiesByEnemy.Add(__instance, val);
				}
			}
			if (heldWalkiesByEnemy.TryGetValue(__instance, out var value2))
			{
				if (((EnemyAI)__instance).isEnemyDead)
				{
					Plugin.LogWarning("Destroying walkie. Enemy dead.");
					Object.DestroyImmediate((Object)(object)value2);
					spawnedEnemies.Remove(__instance);
					heldWalkiesByEnemy.Remove(__instance);
				}
				else
				{
					Transform parent = ((EnemyAI)__instance).eye.parent.parent;
					value2.transform.rotation = parent.rotation * Quaternion.Euler(WalkiePatcher.playerShoulderRotationOffset);
					value2.transform.position = parent.position + parent.rotation * WalkiePatcher.playerShoulderPositionOffset;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class WalkiePatcher
	{
		public static Vector3 localPlayerShoulderPositionOffset = new Vector3(0.125f, 0.4f, 0.125f);

		public static Vector3 playerShoulderPositionOffset = new Vector3(0.15f, -0.05f, 0.25f);

		public static Vector3 playerShoulderRotationOffset = new Vector3(0f, 270f, 100f);

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static WalkieTalkie GetMainWalkie(PlayerControllerB playerController)
		{
			return GetCurrentlySelectedWalkie(playerController) ?? GetReservedWalkie(playerController);
		}

		public static WalkieTalkie GetReservedWalkie(PlayerControllerB playerController)
		{
			ReservedPlayerData value;
			return (WalkieTalkie)((SyncManager.syncReservedItemsList.Contains(Plugin.walkieInfo) && PlayerPatcher.allPlayerData.TryGetValue(playerController, out value)) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static WalkieTalkie GetCurrentlySelectedWalkie(PlayerControllerB playerController)
		{
			return (WalkieTalkie)((playerController.currentItemSlot >= 0 && playerController.currentItemSlot < playerController.ItemSlots.Length) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		[HarmonyPatch(typeof(WalkieTalkie), "PocketItem")]
		[HarmonyPostfix]
		public static void OnPocketWalkie(WalkieTalkie __instance)
		{
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController) ? 23 : 6);
				}
			}
			((GrabbableObject)__instance).parentObject = ((Component)((GrabbableObject)__instance).playerHeldBy.playerBadgeMesh).transform.parent;
		}

		[HarmonyPatch(typeof(WalkieTalkie), "EquipItem")]
		[HarmonyPostfix]
		public static void OnEquipWalkie(WalkieTalkie __instance)
		{
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = 6;
				}
			}
			((GrabbableObject)__instance).parentObject = (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController) ? ((GrabbableObject)__instance).playerHeldBy.localItemHolder : ((GrabbableObject)__instance).playerHeldBy.serverItemHolder);
		}

		[HarmonyPatch(typeof(WalkieTalkie), "DiscardItem")]
		[HarmonyPostfix]
		public static void OnDiscardWalkie(WalkieTalkie __instance)
		{
			Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)val).name.Contains("ScanNode") && !((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger"))
				{
					((Component)val).gameObject.layer = 6;
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void SetPositionOffset(GrabbableObject __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is WalkieTalkie && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance.parentObject != (Object)null && __instance.isPocketed && (Object)(object)__instance == (Object)(object)GetReservedWalkie(__instance.playerHeldBy) && (Object)(object)__instance != (Object)(object)GetCurrentlySelectedWalkie(__instance.playerHeldBy))
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = ((Component)__instance.parentObject).transform.rotation * Quaternion.Euler(playerShoulderRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * playerShoulderPositionOffset;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EnableItemMeshes")]
		[HarmonyPrefix]
		public static void OnEnableItemMeshes(ref bool enable, GrabbableObject __instance)
		{
			if (__instance is WalkieTalkie && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance == (Object)(object)GetReservedWalkie(__instance.playerHeldBy) && !ConfigSettings.hideWalkieMeshShoulder.Value && !ReservedItemPatcher.ReservedItemIsBeingGrabbed(__instance))
			{
				enable = true;
			}
		}
	}
}
namespace ReservedWalkieSlot.Input
{
	internal class IngameKeybinds : LcInputActions
	{
		internal static IngameKeybinds Instance = new IngameKeybinds();

		[InputAction("<Keyboard>/x", Name = "[ReservedItemSlots]\nActivate walkie")]
		public InputAction ActivateWalkieHotkey { get; set; }

		internal static InputActionAsset GetAsset()
		{
			return ((LcInputActions)Instance).Asset;
		}
	}
	internal class InputUtilsCompat
	{
		internal static InputActionAsset Asset => IngameKeybinds.GetAsset();

		internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils");

		public static InputAction ActivateWalkieHotkey => IngameKeybinds.Instance.ActivateWalkieHotkey;
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static InputActionAsset Asset;

		public static InputActionMap ActionMap;

		private static InputAction ActivateWalkieAction;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void AddToKeybindMenu()
		{
			InitKeybinds();
		}

		public static void InitKeybinds()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log("Initializing hotkeys.");
			if (InputUtilsCompat.Enabled)
			{
				Asset = InputUtilsCompat.Asset;
				ActionMap = Asset.actionMaps[0];
				ActivateWalkieAction = InputUtilsCompat.ActivateWalkieHotkey;
			}
			else
			{
				Asset = new InputActionAsset();
				ActionMap = new InputActionMap("ReservedItemSlots");
				InputActionSetupExtensions.AddActionMap(Asset, ActionMap);
				ActivateWalkieAction = InputActionSetupExtensions.AddAction(ActionMap, "ReservedItemSlots.ActivateWalkie", (InputActionType)0, ConfigSettings.activateWalkieKey.Value, (string)null, (string)null, (string)null, (string)null);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable()
		{
			Asset.Enable();
			ActivateWalkieAction.performed += OnPressWalkieButtonPerformed;
			ActivateWalkieAction.canceled += OnReleaseWalkieButtonPerformed;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable()
		{
			Asset.Disable();
			ActivateWalkieAction.performed -= OnPressWalkieButtonPerformed;
			ActivateWalkieAction.canceled -= OnReleaseWalkieButtonPerformed;
		}

		private static void OnPressWalkieButtonPerformed(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject))
			{
				return;
			}
			WalkieTalkie mainWalkie = WalkiePatcher.GetMainWalkie(localPlayerController);
			if (((CallbackContext)(ref context)).performed && !((Object)(object)mainWalkie == (Object)null) && ((GrabbableObject)mainWalkie).isBeingUsed && !ShipBuildModeManager.Instance.InBuildMode)
			{
				float num = (float)Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").GetValue();
				if (!(num < 0.075f))
				{
					Plugin.Log("Speaking into walkie");
					((GrabbableObject)mainWalkie).UseItemOnClient(true);
					Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").SetValue((object)0);
				}
			}
		}

		private static void OnReleaseWalkieButtonPerformed(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && localPlayerController.isPlayerControlled && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
			{
				WalkieTalkie mainWalkie = WalkiePatcher.GetMainWalkie(localPlayerController);
				if (((CallbackContext)(ref context)).canceled && !((Object)(object)mainWalkie == (Object)null))
				{
					Plugin.Log("Not talking into walkie");
					((GrabbableObject)mainWalkie).UseItemOnClient(false);
				}
			}
		}
	}
}

mods/FlipMods-TooManyEmotes-1.8.1/plugins/TooManyEmotes.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Dissonance.Integrations.Unity_NFGO;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using MoreCompany.Cosmetics;
using TMPro;
using TooManyEmotes.Config;
using TooManyEmotes.Input;
using TooManyEmotes.Networking;
using TooManyEmotes.Patches;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.EventSystems;
using UnityEngine.Experimental.Rendering;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TooManyEmotes")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TooManyEmotes")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d6950625-e3a1-4896-a183-87110491bf18")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TooManyEmotes
{
	[HarmonyPatch]
	public static class EmoteMenuManager
	{
		public static GameObject menuGameObject;

		public static RectTransform menuTransform;

		public static CanvasGroup canvasGroup;

		public static RawImage renderTextureImageUI;

		public static TextMeshPro swapPageText;

		public static TextMeshPro currentEmoteText;

		public static RenderTexture renderTexture;

		public static Camera renderingCamera;

		public static GameObject previewPlayerObject;

		public static SkinnedMeshRenderer previewPlayerMesh;

		public static Animator previewPlayerAnimator;

		public static AnimatorOverrideController previewPlayerAnimatorController;

		public static int playerLayer = LayerMask.NameToLayer("Player");

		public static float hoveredAlpha = 0.75f;

		public static float unhoveredAlpha = 0.75f;

		public static Color defaultUIColor = new Color(0.3f, 0.3f, 0.3f);

		public static List<EmoteUIElement> emoteUIElementsList;

		public static int hoveredEmoteUIIndex = -1;

		public static int currentPage = 0;

		public static List<EmoteLoadoutUIElement> emoteLoadoutUIElementsList;

		public static List<List<UnlockableEmote>> emoteLoadouts;

		public static Color selectedLoadoutUIColor = new Color(0.2f, 0.2f, 1f);

		public static int currentLoadoutIndex = -1;

		public static int numLoadouts = 3;

		public static int hoveredLoadoutUIIndex = -1;

		public static QuickMenuManager quickMenuManager => StartOfRound.Instance?.localPlayerController?.quickMenuManager;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static int playerLayerMask => 1 << playerLayer;

		public static int hoveredEmoteIndex => (hoveredEmoteUIIndex >= 0) ? (hoveredEmoteUIIndex + 8 * currentPage) : (-1);

		public static int numPages => (currentLoadoutEmotesList != null) ? (Mathf.Max((currentLoadoutEmotesList.Count - 1) / emoteUIElementsList.Count, 0) + 1) : 0;

		public static UnlockableEmote previewingEmote => (currentLoadoutEmotesList != null && hoveredEmoteIndex >= 0 && hoveredEmoteIndex < currentLoadoutEmotesList.Count) ? currentLoadoutEmotesList[hoveredEmoteIndex] : null;

		public static List<UnlockableEmote> currentLoadoutEmotesList => (emoteLoadouts != null && currentLoadoutIndex >= 0 && currentLoadoutIndex < emoteLoadouts.Count) ? emoteLoadouts[currentLoadoutIndex] : null;

		public static bool isMenuOpen => (Object)(object)menuGameObject != (Object)null && menuGameObject.activeSelf;

		[HarmonyPatch(typeof(HUDManager), "Start")]
		[HarmonyPostfix]
		public static void InitializeUI(HUDManager __instance)
		{
			if (!ConfigSettings.disableEmotesForSelf.Value && !((Object)(object)Plugin.radialMenuPrefab == (Object)null))
			{
				menuGameObject = Object.Instantiate<GameObject>(Plugin.radialMenuPrefab, __instance.HUDContainer.transform.parent);
				menuGameObject.transform.SetAsLastSibling();
				((Object)menuGameObject).name = "EmotesRadialMenu";
				menuTransform = menuGameObject.GetComponent<RectTransform>();
				renderTextureImageUI = menuGameObject.GetComponentInChildren<RawImage>();
				Transform transform = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialElements")).transform;
				swapPageText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/SwapPageText")).GetComponent<TextMeshPro>();
				currentEmoteText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/CurrentEmoteText")).GetComponent<TextMeshPro>();
				((TMP_Text)currentEmoteText).text = "";
				emoteUIElementsList = new List<EmoteUIElement>();
				currentPage = 0;
				hoveredEmoteUIIndex = -1;
				for (int i = 0; i < transform.childCount; i++)
				{
					Transform child = transform.GetChild(i);
					EmoteUIElement item = new EmoteUIElement
					{
						uiGameObject = ((Component)child).gameObject,
						id = i,
						backgroundImage = ((Component)child).GetComponentInChildren<Image>(),
						textContainer = ((Component)child).GetComponentInChildren<TextMeshPro>()
					};
					emoteUIElementsList.Add(item);
				}
				EmoteLoadoutUIElement.uiCount = 0;
				Transform transform2 = ((Component)((Transform)menuTransform).Find("RadialMenuUI/EmoteLoadouts")).transform;
				((Component)transform2).gameObject.AddComponent<EmoteLoadoutUIContainer>();
				emoteLoadoutUIElementsList = new List<EmoteLoadoutUIElement>();
				emoteLoadoutUIElementsList.Add(((Component)transform2.GetChild(0)).gameObject.AddComponent<EmoteLoadoutUIElement>());
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				for (int j = 0; j < emoteLoadoutUIElementsList.Count; j++)
				{
					((Object)emoteLoadoutUIElementsList[j]).name = "EmoteLoadout_" + j;
				}
				emoteLoadoutUIElementsList[0].loadoutName = "Favorites";
				emoteLoadoutUIElementsList[1].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[3]}>Legendary</color>";
				emoteLoadoutUIElementsList[2].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[2]}>Rare</color>";
				emoteLoadoutUIElementsList[3].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[1]}>Uncommon</color>";
				emoteLoadoutUIElementsList[4].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[0]}>Common</color>";
				emoteLoadoutUIElementsList[5].loadoutName = "Complementary";
				emoteLoadoutUIElementsList[6].loadoutName = "All";
				SaveManager.LoadFavoritedEmotes();
				emoteLoadouts = new List<List<UnlockableEmote>>
				{
					StartOfRoundPatcher.unlockedFavoriteEmotes,
					StartOfRoundPatcher.unlockedEmotesTier3,
					StartOfRoundPatcher.unlockedEmotesTier2,
					StartOfRoundPatcher.unlockedEmotesTier1,
					StartOfRoundPatcher.unlockedEmotesTier0,
					StartOfRoundPatcher.complementaryEmotes,
					StartOfRoundPatcher.unlockedEmotes
				};
				if (currentLoadoutIndex < 0 || currentLoadoutIndex >= emoteLoadouts.Count)
				{
					currentLoadoutIndex = emoteLoadouts.Count - 1;
				}
				InitializeAnimationRenderer();
				menuGameObject.SetActive(false);
			}
		}

		[HarmonyPatch(typeof(HUDManager), "Update")]
		[HarmonyPostfix]
		public static void GetInput()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigSettings.disableEmotesForSelf.Value || (Object)(object)previewPlayerAnimatorController == (Object)null || !isMenuOpen)
			{
				return;
			}
			if (EmoteLoadoutUIContainer.hovered || hoveredLoadoutUIIndex != -1)
			{
				if (hoveredEmoteUIIndex != -1)
				{
					OnHoveredNewElement(-1);
				}
				return;
			}
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)(Screen.width / 2), (float)(Screen.height / 2));
			Vector2 val3 = val - val2;
			int num = -1;
			if (((Vector2)(ref val3)).magnitude / (float)Screen.height >= 0.17f)
			{
				float num2 = Mathf.Atan2(val3.y, 0f - val3.x) * 57.29578f - 67.5f;
				if (num2 < 0f)
				{
					num2 += 360f;
				}
				num = Mathf.FloorToInt(num2 / 45f);
			}
			if (num != hoveredEmoteUIIndex)
			{
				OnHoveredNewElement(num);
			}
		}

		public static void OnHoveredNewLoadoutElement(int index)
		{
			if (hoveredLoadoutUIIndex == index)
			{
				return;
			}
			hoveredLoadoutUIIndex = index;
			foreach (EmoteLoadoutUIElement emoteLoadoutUIElements in emoteLoadoutUIElementsList)
			{
				emoteLoadoutUIElements.OnHover(emoteLoadoutUIElements.id == index);
			}
		}

		public static void OnHoveredNewElement(int index)
		{
			if (hoveredEmoteUIIndex != -1 && hoveredEmoteUIIndex != index)
			{
				emoteUIElementsList[hoveredEmoteUIIndex].OnHover(hovered: false);
			}
			if (index != -1)
			{
				emoteUIElementsList[index].OnHover();
			}
			hoveredEmoteUIIndex = index;
			SetPreviewAnimation(hoveredEmoteIndex);
		}

		public static void SwapPrevPage()
		{
			currentPage--;
			if (currentPage < 0)
			{
				currentPage = numPages - 1;
			}
			UpdateEmoteWheel();
		}

		public static void SwapNextPage()
		{
			currentPage++;
			if (currentPage >= numPages)
			{
				currentPage = 0;
			}
			UpdateEmoteWheel();
		}

		public static void UpdateEmoteWheel()
		{
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			currentPage = Mathf.Clamp(currentPage, 0, numPages - 1);
			((TMP_Text)swapPageText).text = $"[{currentPage + 1} / {numPages}]\n[Mouse Scroll]";
			for (int i = 0; i < emoteLoadoutUIElementsList.Count; i++)
			{
				EmoteLoadoutUIElement emoteLoadoutUIElement = emoteLoadoutUIElementsList[i];
				emoteLoadoutUIElement.OnHover(hoveredLoadoutUIIndex == emoteLoadoutUIElement.id);
			}
			for (int j = 0; j < emoteLoadouts.Count; j++)
			{
				List<UnlockableEmote> list = emoteLoadouts[j];
				EmoteLoadoutUIElement emoteLoadoutUIElement2 = emoteLoadoutUIElementsList[j];
				string text = ((TMP_Text)emoteLoadoutUIElement2.textContainer).text;
				int num = text.IndexOf(" ");
				text = text[..((num == -1) ? text.Length : num)] + " [" + list.Count + "]";
				((TMP_Text)emoteLoadoutUIElement2.textContainer).text = text;
			}
			for (int k = 0; k < emoteUIElementsList.Count; k++)
			{
				EmoteUIElement emoteUIElement = emoteUIElementsList[k];
				int num2 = k + 8 * currentPage;
				((TMP_Text)emoteUIElement.textContainer).text = "";
				emoteUIElement.emote = null;
				Color baseColor = defaultUIColor;
				if (num2 < currentLoadoutEmotesList.Count)
				{
					UnlockableEmote unlockableEmote = currentLoadoutEmotesList[num2];
					if (unlockableEmote != null)
					{
						emoteUIElement.emote = unlockableEmote;
						((TMP_Text)emoteUIElement.textContainer).text = unlockableEmote.displayName;
					}
				}
				emoteUIElement.baseColor = baseColor;
				emoteUIElement.OnHover(hovered: false);
			}
			if (hoveredEmoteUIIndex >= 0 && hoveredEmoteUIIndex < 8)
			{
				OnHoveredNewElement(hoveredEmoteUIIndex);
			}
		}

		public static void SetPreviewAnimation(int emoteIndex)
		{
			if (emoteIndex >= 0 && emoteIndex < currentLoadoutEmotesList.Count && currentLoadoutEmotesList[emoteIndex] != null)
			{
				UnlockableEmote unlockableEmote = currentLoadoutEmotesList[emoteIndex];
				previewPlayerObject.SetActive(true);
				((Behaviour)renderingCamera).enabled = true;
				previewPlayerAnimatorController["EmoteStart"] = unlockableEmote.animationClip;
				previewPlayerAnimatorController["EmoteLoop"] = (((Object)(object)unlockableEmote.transitionsToClip != (Object)null) ? unlockableEmote.transitionsToClip : null);
				previewPlayerAnimator.SetBool("hasTransition", (Object)(object)unlockableEmote.transitionsToClip != (Object)null);
				previewPlayerAnimator.Play("EmoteStart", 0, 0f);
				((TMP_Text)currentEmoteText).text = "[" + unlockableEmote.displayNameColorCoded + "]\n[MMB] " + (StartOfRoundPatcher.allFavoriteEmotes.Contains(unlockableEmote.emoteName) ? "Unfavorite" : "Favorite");
			}
			else
			{
				previewPlayerAnimatorController["EmoteStart"] = null;
				previewPlayerAnimatorController["EmoteLoop"] = null;
				previewPlayerObject.SetActive(false);
				((TMP_Text)currentEmoteText).text = "";
				DisableRenderCameraNextFrame();
			}
		}

		public static void DisableRenderCameraNextFrame()
		{
			((MonoBehaviour)HUDManager.Instance).StartCoroutine(DisableRenderCameraNextFrameCoroutine());
			static IEnumerator DisableRenderCameraNextFrameCoroutine()
			{
				yield return null;
				((Behaviour)renderingCamera).enabled = false;
			}
		}

		public static void SetCurrentEmoteLoadout(int loadoutIndex)
		{
			if (currentLoadoutIndex != loadoutIndex)
			{
				currentPage = 0;
				currentLoadoutIndex = loadoutIndex;
				UpdateEmoteWheel();
			}
		}

		public static void ToggleFavoriteHoveredEmote()
		{
			if (isMenuOpen && previewingEmote != null)
			{
				string emoteName = previewingEmote.emoteName;
				if (StartOfRoundPatcher.allFavoriteEmotes.Contains(emoteName))
				{
					StartOfRoundPatcher.allFavoriteEmotes.Remove(emoteName);
				}
				else
				{
					StartOfRoundPatcher.allFavoriteEmotes.Add(emoteName);
				}
				StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes();
				SaveManager.SaveFavoritedEmotes();
				UpdateEmoteWheel();
			}
		}

		public static void ToggleEmoteMenu()
		{
			if (!isMenuOpen)
			{
				OpenEmoteMenu();
			}
			else
			{
				CloseEmoteMenu();
			}
		}

		public static void OpenEmoteMenu()
		{
			menuGameObject.SetActive(true);
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			quickMenuManager.isMenuOpen = true;
			((Renderer)previewPlayerMesh).material = ((Renderer)localPlayerController.thisPlayerModel).material;
			UpdateEmoteWheel();
		}

		public static void CloseEmoteMenu()
		{
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			localPlayerController.isFreeCamera = false;
			menuGameObject.SetActive(false);
			quickMenuManager.CloseQuickMenu();
		}

		public static bool CanOpenEmoteMenu()
		{
			if ((quickMenuManager.isMenuOpen && !isMenuOpen) || (Object)(object)previewPlayerObject == (Object)null)
			{
				return false;
			}
			if (localPlayerController.isPlayerDead || localPlayerController.inTerminalMenu || localPlayerController.isTypingChat || localPlayerController.isPlayerDead || localPlayerController.inSpecialInteractAnimation || localPlayerController.isGrabbingObjectAnimation || localPlayerController.inShockingMinigame || localPlayerController.isClimbingLadder || localPlayerController.isSinking || (Object)(object)localPlayerController.inAnimationWithEnemy != (Object)null)
			{
				return false;
			}
			return true;
		}

		private static void InitializeAnimationRenderer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00af: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			renderingCamera = new GameObject("AnimationRenderingCamera").AddComponent<Camera>();
			Object.Destroy((Object)(object)((Component)renderingCamera).GetComponent<AudioListener>());
			renderingCamera.cullingMask = playerLayerMask;
			renderingCamera.clearFlags = (CameraClearFlags)2;
			renderingCamera.cameraType = (CameraType)4;
			renderingCamera.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0f);
			renderingCamera.allowHDR = false;
			renderingCamera.allowMSAA = false;
			renderingCamera.farClipPlane = 5f;
			renderTexture = new RenderTexture(1024, 1024, 24);
			renderTexture.format = (RenderTextureFormat)0;
			renderTexture.graphicsFormat = (GraphicsFormat)8;
			renderTexture.depthStencilFormat = (GraphicsFormat)92;
			renderingCamera.targetTexture = renderTexture;
			((Component)renderingCamera).transform.position = Vector3.down * 1000f;
			renderTextureImageUI.texture = (Texture)(object)renderTexture;
			Light val = new GameObject("Spotlight").AddComponent<Light>();
			val.type = (LightType)0;
			((Component)val).transform.position = ((Component)renderingCamera).transform.position;
			((Component)val).transform.parent = ((Component)renderingCamera).transform;
			((Component)val).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			val.intensity = 50f;
			val.range = 40f;
			val.innerSpotAngle = 100f;
			val.spotAngle = 120f;
			((Component)val).gameObject.layer = playerLayer;
			DisableRenderCameraNextFrame();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void InitializePlayerCloneRenderObject(PlayerControllerB __instance)
		{
			if (!ConfigSettings.disableEmotesForSelf.Value && !((Object)(object)Plugin.radialMenuPrefab == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(InitPlayerCloneAfterSpawnAnimation());
			}
			IEnumerator InitPlayerCloneAfterSpawnAnimation()
			{
				yield return (object)new WaitForSeconds(2f);
				previewPlayerObject = Object.Instantiate<GameObject>(((Component)__instance).gameObject, ((Component)renderingCamera).transform);
				((Object)previewPlayerObject).name = "PreviewPlayerAnimationObject";
				GameObject modelGameObject = ((Component)previewPlayerObject.transform.Find("ScavengerModel")).gameObject;
				GameObject metarigGameObject = ((Component)modelGameObject.transform.Find("metarig")).gameObject;
				PlayerControllerB copyPlayerController = previewPlayerObject.GetComponentInChildren<PlayerControllerB>();
				((Renderer)copyPlayerController.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				previewPlayerMesh = copyPlayerController.thisPlayerModel;
				Object.Destroy((Object)(object)modelGameObject.GetComponentInChildren<LODGroup>());
				Object.DestroyImmediate((Object)(object)metarigGameObject.GetComponentInChildren<RigBuilder>());
				Object.DestroyImmediate((Object)(object)copyPlayerController.playerBodyAnimator);
				previewPlayerAnimator = metarigGameObject.AddComponent<Animator>();
				previewPlayerAnimatorController = new AnimatorOverrideController(Plugin.previewAnimatorController);
				previewPlayerAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)previewPlayerAnimatorController;
				previewPlayerAnimator.Play("EmoteStart", 0, 0f);
				Object.Destroy((Object)(object)previewPlayerObject.GetComponent<NfgoPlayer>());
				foreach (Transform item in previewPlayerObject.transform)
				{
					Transform child3 = item;
					if (((Object)child3).name != "ScavengerModel")
					{
						Object.Destroy((Object)(object)((Component)child3).gameObject);
					}
				}
				foreach (Transform item2 in modelGameObject.transform)
				{
					Transform child2 = item2;
					if (((Object)child2).name != "LOD1" && ((Object)child2).name != "metarig")
					{
						Object.Destroy((Object)(object)((Component)child2).gameObject);
					}
				}
				foreach (Transform item3 in metarigGameObject.transform)
				{
					Transform child = item3;
					if (((Object)child).name != "spine")
					{
						Object.Destroy((Object)(object)((Component)child).gameObject);
					}
				}
				previewPlayerObject.transform.position = ((Component)renderingCamera).transform.position + ((Component)renderingCamera).transform.forward * 2.8f + Vector3.down * 1.35f;
				previewPlayerObject.transform.LookAt(new Vector3(((Component)renderingCamera).transform.position.x, previewPlayerObject.transform.position.y, ((Component)renderingCamera).transform.position.z));
				SetObjectLayerRecursive(previewPlayerObject, playerLayer);
				MonoBehaviour[] components = previewPlayerObject.GetComponents<MonoBehaviour>();
				foreach (MonoBehaviour script in components)
				{
					Object.Destroy((Object)(object)script);
				}
			}
		}

		private static void SetObjectLayerRecursive(GameObject obj, int layer)
		{
			if (!((Object)(object)obj == (Object)null))
			{
				obj.layer = layer;
				for (int i = 0; i < obj.transform.childCount; i++)
				{
					Transform child = obj.transform.GetChild(i);
					SetObjectLayerRecursive((child != null) ? ((Component)child).gameObject : null, layer);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool OnScrollMouse(CallbackContext context, PlayerControllerB __instance)
		{
			if (ConfigSettings.disableEmotesForSelf.Value || (Object)(object)__instance != (Object)(object)localPlayerController || !isMenuOpen || !((CallbackContext)(ref context)).performed)
			{
				return true;
			}
			if (numPages == 0 || (numPages == 1 && currentPage == 0))
			{
				return false;
			}
			if (((CallbackContext)(ref context)).ReadValue<float>() < 0f && !ConfigSettings.reverseEmoteWheelScrollDirection.Value)
			{
				SwapPrevPage();
			}
			else
			{
				SwapNextPage();
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ItemSecondaryUse_performed")]
		[HarmonyPrefix]
		public static bool PreventItemSecondaryUseInMenu(CallbackContext context)
		{
			if (ConfigSettings.disableEmotesForSelf.Value)
			{
				return true;
			}
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ItemTertiaryUse_performed")]
		[HarmonyPrefix]
		public static bool PreventItemTertiaryUseInMenu(CallbackContext context)
		{
			if (ConfigSettings.disableEmotesForSelf.Value)
			{
				return true;
			}
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Interact_performed")]
		[HarmonyPrefix]
		public static bool PreventInteractInMenu(CallbackContext context)
		{
			if (ConfigSettings.disableEmotesForSelf.Value)
			{
				return true;
			}
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
		[HarmonyPrefix]
		public static bool OnOpenQuickMenu()
		{
			if (!isMenuOpen)
			{
				return true;
			}
			CloseEmoteMenu();
			return false;
		}

		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		[HarmonyPostfix]
		public static void OnCloseQuickMenu()
		{
			if (isMenuOpen)
			{
				CloseEmoteMenu();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyPostfix]
		public static void OnLocalPlayerDeath(Vector3 bodyVelocity, PlayerControllerB __instance)
		{
			if (isMenuOpen && (Object)(object)__instance == (Object)(object)localPlayerController && __instance.isPlayerDead)
			{
				CloseEmoteMenu();
			}
		}
	}
	public class EmoteUIElement
	{
		public GameObject uiGameObject;

		public int id;

		public Image backgroundImage;

		public TextMeshPro textContainer;

		public Color baseColor;

		public UnlockableEmote emote;

		public void OnHover(bool hovered = true)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Color color = baseColor * (hovered ? 1f : 0.5f);
			color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha);
			((Graphic)backgroundImage).color = color;
		}
	}
	public class EmoteLoadoutUIElement : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public static int uiCount;

		public int id;

		public string loadoutName;

		public Image backgroundImage;

		public TextMeshPro textContainer;

		private void Awake()
		{
			id = uiCount++;
			backgroundImage = ((Component)this).GetComponentInChildren<Image>();
			textContainer = ((Component)this).GetComponentInChildren<TextMeshPro>();
		}

		private void Start()
		{
			((TMP_Text)textContainer).text = loadoutName;
		}

		public void OnHover(bool hovered = true)
		{
			//IL_0015: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Color color = ((EmoteMenuManager.currentLoadoutIndex == id) ? EmoteMenuManager.selectedLoadoutUIColor : EmoteMenuManager.defaultUIColor) * (hovered ? 1f : 0.5f);
			color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha);
			((Graphic)backgroundImage).color = color;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			EmoteMenuManager.OnHoveredNewLoadoutElement(id);
			OnHover();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			EmoteMenuManager.OnHoveredNewLoadoutElement(-1);
			OnHover(hovered: false);
		}
	}
	public class EmoteLoadoutUIContainer : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public static bool hovered;

		public void OnPointerEnter(PointerEventData eventData)
		{
			hovered = true;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			hovered = false;
		}
	}
	public class PlayerData
	{
		public PlayerControllerB playerController;

		public UnlockableEmote performingEmote;

		public bool isLocalPlayer => (Object)(object)playerController == (Object)(object)StartOfRound.Instance?.localPlayerController;

		public string name => ((Object)playerController).name;

		public ulong clientId => playerController.actualClientId;

		public ulong playerId => playerController.playerClientId;

		public ulong steamId => playerController.playerSteamId;

		public string username => playerController.playerUsername;

		public Animator animator => playerController.playerBodyAnimator;

		public AnimatorOverrideController animatorController
		{
			get
			{
				RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController;
				return (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
			}
			set
			{
				animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)value;
			}
		}

		public bool animatorControllerIsOverride => (Object)(object)animator.runtimeAnimatorController != (Object)null && animator.runtimeAnimatorController is AnimatorOverrideController;

		public RigBuilder rigBuilder => ((Component)playerController).GetComponentInChildren<RigBuilder>();

		public int currentEmoteNumber
		{
			get
			{
				return animator.GetInteger("emoteNumber");
			}
			set
			{
				animator.SetInteger("emoteNumber", value);
			}
		}

		public bool isPerformingEmote => performingEmote != null;

		public float normalizedTimeAnimation
		{
			get
			{
				//IL_0008: 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)
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(1);
				return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
			}
		}

		public void ConvertAnimatorControllerToOverride()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			Plugin.LogWarning("Converting animator controller to override for player: " + ((Object)playerController).name);
			if ((Object)(object)animator != (Object)null && !(animator.runtimeAnimatorController is AnimatorOverrideController))
			{
				animator.runtimeAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(animator.runtimeAnimatorController);
			}
		}

		public void EnableRigBuilder(bool enable)
		{
			Plugin.Log((enable ? "Enabling " : "Disabling ") + "rigbuilder for player with id: " + playerController.actualClientId);
			if (enable)
			{
				((MonoBehaviour)playerController).StartCoroutine(EnableRigBuilder());
			}
			else
			{
				((Behaviour)rigBuilder).enabled = enable;
			}
			IEnumerator EnableRigBuilder()
			{
				TryGetCurrentAnimationClip(out var currentAnimationClip);
				int currentEmoteNumber = playerController.playerBodyAnimator.GetInteger("emoteNumber");
				AnimatorStateInfo currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
				int prevState = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
				currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
				float normalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
				SetCurrentAnimationClip(Plugin.idleClip);
				playerController.playerBodyAnimator.SetInteger("emoteNumber", 1);
				playerController.playerBodyAnimator.Play("Dance1", 1, 0f);
				yield return (object)new WaitForEndOfFrame();
				SetCurrentAnimationClip(currentAnimationClip);
				playerController.playerBodyAnimator.SetInteger("emoteNumber", currentEmoteNumber);
				currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
				int currentState = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
				if (currentState != prevState)
				{
					playerController.playerBodyAnimator.CrossFadeInFixedTime(prevState, 0.1f, 1);
				}
				else
				{
					playerController.playerBodyAnimator.Play(prevState, 1, normalizedTime);
				}
				((Behaviour)rigBuilder).enabled = enable;
			}
		}

		public bool TryGetCurrentAnimationClip(out AnimationClip animationClip, string stateName = "Dance1")
		{
			animationClip = null;
			try
			{
				if (!(animator.runtimeAnimatorController is AnimatorOverrideController))
				{
					ConvertAnimatorControllerToOverride();
				}
				animationClip = animatorController[stateName];
			}
			catch
			{
			}
			return (Object)(object)animationClip != (Object)null;
		}

		public void SetCurrentAnimationClip(AnimationClip clip, string stateName = "Dance1")
		{
			if (!(animator.runtimeAnimatorController is AnimatorOverrideController))
			{
				ConvertAnimatorControllerToOverride();
			}
			animatorController[stateName] = clip;
		}

		public bool IsEmoteLoaded()
		{
			UnlockableEmote emote;
			return TryGetLoadedEmote(out emote);
		}

		public bool TryGetLoadedEmote(out UnlockableEmote emote)
		{
			emote = null;
			if (TryGetCurrentAnimationClip(out var animationClip))
			{
				string key = ((Object)animationClip).name.Replace("_loop", "").Replace("_start", "").Replace("_pose", "");
				if (StartOfRoundPatcher.allUnlockableEmotesDict.TryGetValue(key, out var value))
				{
					emote = value;
				}
			}
			return emote != null;
		}

		public void PlayEmoteAtTime(UnlockableEmote emote, AnimationClip overrideClip = null, float normalizedTime = 0f, bool playEmoteEndOfFrame = false)
		{
			if (playEmoteEndOfFrame)
			{
				((MonoBehaviour)playerController).StartCoroutine(PlayEmoteEndOfFrame());
				return;
			}
			AnimationClip val = (((Object)(object)overrideClip != (Object)null) ? overrideClip : emote.animationClip);
			SetCurrentAnimationClip(val);
			playerController.playerBodyAnimator.Play("Dance1", 1, normalizedTime);
			if ((Object)(object)val == (Object)(object)emote.animationClip && (Object)(object)emote.transitionsToClip != (Object)null)
			{
				((MonoBehaviour)playerController).StartCoroutine(TransitionToLoopEmote(emote));
			}
			else if (!((Motion)val).isLooping && !emote.isPose)
			{
				((MonoBehaviour)playerController).StartCoroutine(StopEmoteAfterFinished(emote));
			}
			if (isLocalPlayer)
			{
				ThirdPersonEmoteController.OnStartCustomEmoteLocal();
				if ((Object)(object)playerController.localItemHolder == (Object)(object)playerController.currentlyHeldObjectServer?.parentObject)
				{
					playerController.currentlyHeldObjectServer.parentObject = playerController.serverItemHolder;
				}
			}
			IEnumerator PlayEmoteEndOfFrame()
			{
				yield return (object)new WaitForEndOfFrame();
				PlayEmoteAtTime(emote, overrideClip, normalizedTime);
			}
		}

		private IEnumerator TransitionToLoopEmote(UnlockableEmote emote)
		{
			yield return (object)new WaitForSeconds(emote.animationClip.length);
			if (TryGetCurrentAnimationClip(out var currentAnimationClip) && (Object)(object)currentAnimationClip == (Object)(object)emote.animationClip && (normalizedTimeAnimation >= 0.9f || !isLocalPlayer))
			{
				SetCurrentAnimationClip(((Object)(object)emote.transitionsToClip != (Object)null) ? emote.transitionsToClip : PlayerPatcher.defaultDance1Clip);
				playerController.playerBodyAnimator.Play("Dance1", 1, 0f);
			}
		}

		private IEnumerator StopEmoteAfterFinished(UnlockableEmote emote)
		{
			yield return (object)new WaitForSeconds(emote.animationClip.length);
			if (TryGetCurrentAnimationClip(out var currentAnimationClip) && (Object)(object)currentAnimationClip == (Object)(object)emote.animationClip && (normalizedTimeAnimation >= 0.9f || !isLocalPlayer))
			{
				playerController.performingEmote = false;
				if (((NetworkBehaviour)playerController).IsOwner)
				{
					playerController.StopPerformingEmoteServerRpc();
				}
			}
		}

		public PlayerData(PlayerControllerB playerController)
		{
			this.playerController = playerController;
		}
	}
	public class UnlockableEmote
	{
		public int emoteId;

		public string emoteName;

		public string randomEmotePoolName = "";

		public string displayName = "";

		public bool purchasable = true;

		public AnimationClip animationClip;

		public AnimationClip transitionsToClip = null;

		public List<UnlockableEmote> randomEmotePool;

		public bool complementary = false;

		public bool isPose = false;

		public bool canSyncEmote = false;

		public bool favorite = false;

		public int rarity = 0;

		public static string[] rarityColorCodes = new string[4]
		{
			ConfigSettings.emoteNameColorTier0.Value,
			ConfigSettings.emoteNameColorTier1.Value,
			ConfigSettings.emoteNameColorTier2.Value,
			ConfigSettings.emoteNameColorTier3.Value
		};

		public string displayNameColorCoded => $"<color={nameColor}>{displayName}</color>";

		public bool loopable => ((Motion)animationClip).isLooping || ((Object)(object)transitionsToClip != (Object)null && ((Motion)transitionsToClip).isLooping);

		public string rarityText
		{
			get
			{
				if (rarity == 0)
				{
					return "Common";
				}
				if (rarity == 1)
				{
					return "Uncommon";
				}
				if (rarity == 2)
				{
					return "Rare";
				}
				if (rarity == 3)
				{
					return "Legendary";
				}
				return "Invalid";
			}
		}

		public int price
		{
			get
			{
				int num = -1;
				if (complementary)
				{
					num = 0;
				}
				else if (rarity == 0)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier0;
				}
				else if (rarity == 1)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier1;
				}
				else if (rarity == 2)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier2;
				}
				else if (rarity == 3)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier3;
				}
				return (int)Mathf.Max((float)num * ConfigSync.instance.syncPriceMultiplierEmotesStore, 0f);
			}
		}

		public string nameColor => rarityColorCodes[rarity];

		public bool ClipIsInEmote(AnimationClip clip)
		{
			return (Object)(object)clip != (Object)null && ((Object)(object)clip == (Object)(object)animationClip || (Object)(object)clip == (Object)(object)transitionsToClip);
		}
	}
	[BepInPlugin("FlipMods.TooManyEmotes", "TooManyEmotes", "1.8.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		public static List<AnimationClip> customAnimationClips;

		public static HashSet<AnimationClip> customAnimationClipsHash;

		public static Dictionary<string, AnimationClip> customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>();

		public static List<AnimationClip> complementaryAnimationClips;

		public static List<AnimationClip> animationClipsTier0;

		public static List<AnimationClip> animationClipsTier1;

		public static List<AnimationClip> animationClipsTier2;

		public static List<AnimationClip> animationClipsTier3;

		public static AnimationClip idleClip;

		public static GameObject radialMenuPrefab;

		public static RuntimeAnimatorController previewAnimatorController;

		public static Dictionary<string, AudioClip> musicClips;

		private void Awake()
		{
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			Keybinds.InitKeybinds();
			customAnimationClips = new List<AnimationClip>();
			customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>();
			complementaryAnimationClips = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_complementary"));
			animationClipsTier0 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_0"));
			animationClipsTier1 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_1"));
			animationClipsTier2 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_2"));
			animationClipsTier3 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_3"));
			AnimationClip[] array = LoadEmoteAssetBundle("Assets/emotes_misc");
			if (array != null && array.Length >= 1)
			{
				AnimationClip[] array2 = array;
				foreach (AnimationClip val in array2)
				{
					if (((Object)val).name.Contains("idle"))
					{
						idleClip = val;
					}
				}
			}
			customAnimationClips.AddRange(complementaryAnimationClips);
			customAnimationClips.AddRange(animationClipsTier0);
			customAnimationClips.AddRange(animationClipsTier1);
			customAnimationClips.AddRange(animationClipsTier2);
			customAnimationClips.AddRange(animationClipsTier3);
			foreach (AnimationClip customAnimationClip in customAnimationClips)
			{
				if (((Object)customAnimationClip).name.StartsWith("fn_"))
				{
					((Object)customAnimationClip).name = ((Object)customAnimationClip).name.Replace("fn_", "");
				}
				if (((Object)customAnimationClip).name.EndsWith("_loop"))
				{
					customAnimationClipsLoopDict.Add(((Object)customAnimationClip).name, customAnimationClip);
				}
			}
			foreach (AnimationClip value in customAnimationClipsLoopDict.Values)
			{
				customAnimationClips.Remove(value);
			}
			customAnimationClipsHash = new HashSet<AnimationClip>(customAnimationClips);
			customAnimationClipsHash.UnionWith(customAnimationClipsLoopDict.Values);
			LoadRadialMenuAsset();
			_harmony = new Harmony("TooManyEmotes");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"TooManyEmotes loaded");
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		private static AnimationClip[] LoadEmoteAssetBundle(string assetBundleName)
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), assetBundleName);
				AssetBundle val = AssetBundle.LoadFromFile(text);
				AnimationClip[] array = val.LoadAllAssets<AnimationClip>();
				Log($"Successfully loaded {array.Length} animation clips from asset bundle: {assetBundleName}");
				return array;
			}
			catch
			{
				LogError("Failed to load emotes asset bundle: " + assetBundleName + ".");
				return (AnimationClip[])(object)new AnimationClip[0];
			}
		}

		public static void LoadRadialMenuAsset()
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), "Assets/radial_menu");
				AssetBundle val = AssetBundle.LoadFromFile(text);
				radialMenuPrefab = val.LoadAsset<GameObject>("RadialMenu");
				previewAnimatorController = val.LoadAsset<RuntimeAnimatorController>("PreviewAnimatorController");
				Log("Successfully loaded radial menu asset.");
			}
			catch
			{
				LogError("Failed to load radial menu asset.");
			}
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogWarning(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.TooManyEmotes";

		public const string PLUGIN_NAME = "TooManyEmotes";

		public const string PLUGIN_VERSION = "1.8.1";
	}
}
namespace TooManyEmotes.Config
{
	public static class ConfigSettings
	{
		public static ConfigEntry<bool> unlockEverything;

		public static ConfigEntry<bool> shareEverything;

		public static ConfigEntry<bool> syncUnsharedEmotes;

		public static ConfigEntry<bool> enableMovingWhileEmoting;

		public static ConfigEntry<bool> disableRaritySystem;

		public static ConfigEntry<int> basePriceEmoteRaritySystemDisabled;

		public static ConfigEntry<int> startingEmoteCredits;

		public static ConfigEntry<float> addEmoteCreditsMultiplier;

		public static ConfigEntry<bool> purchaseEmotesWithDefaultCurrency;

		public static ConfigEntry<float> priceMultiplierEmotesStore;

		public static ConfigEntry<int> basePriceEmoteTier0;

		public static ConfigEntry<int> basePriceEmoteTier1;

		public static ConfigEntry<int> basePriceEmoteTier2;

		public static ConfigEntry<int> basePriceEmoteTier3;

		public static ConfigEntry<int> numEmotesStoreRotation;

		public static ConfigEntry<float> rotationChanceEmoteTier0;

		public static ConfigEntry<float> rotationChanceEmoteTier1;

		public static ConfigEntry<float> rotationChanceEmoteTier2;

		public static ConfigEntry<float> rotationChanceEmoteTier3;

		public static ConfigEntry<bool> enableMaskedEnemiesEmoting;

		public static ConfigEntry<float> maskedEnemiesEmoteChanceOnEncounter;

		public static ConfigEntry<bool> maskedEnemiesAlwaysEmoteOnFirstEncounter;

		public static ConfigEntry<bool> enableSyncingEmotesWithMaskedEnemies;

		public static ConfigEntry<bool> overrideStopAndStareDuration;

		public static ConfigEntry<string> maskedEnemyEmoteRandomDelay;

		public static ConfigEntry<string> maskedEnemyEmoteRandomDuration;

		public static ConfigEntry<bool> disableEmotesForSelf;

		public static ConfigEntry<string> openEmoteMenuKeybind;

		public static ConfigEntry<string> rotateCharacterInEmoteKeybind;

		public static ConfigEntry<bool> toggleRotateCharacterInEmote;

		public static ConfigEntry<bool> toggleEmoteMenu;

		public static ConfigEntry<bool> reverseEmoteWheelScrollDirection;

		public static ConfigEntry<string> quickEmoteFavorite1Keybind;

		public static ConfigEntry<string> quickEmoteFavorite2Keybind;

		public static ConfigEntry<string> quickEmoteFavorite3Keybind;

		public static ConfigEntry<string> quickEmoteFavorite4Keybind;

		public static ConfigEntry<string> quickEmoteFavorite5Keybind;

		public static ConfigEntry<string> quickEmoteFavorite6Keybind;

		public static ConfigEntry<string> quickEmoteFavorite7Keybind;

		public static ConfigEntry<string> quickEmoteFavorite8Keybind;

		public static ConfigEntry<string> emoteNameColorTier0;

		public static ConfigEntry<string> emoteNameColorTier1;

		public static ConfigEntry<string> emoteNameColorTier2;

		public static ConfigEntry<string> emoteNameColorTier3;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static List<string> configSections = new List<string>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			unlockEverything = AddConfigEntry("Emote Settings", "I am a Party Pooper", defaultValue: false, "[Host only] If true, every emote will be unlocked in your emote wheel at the start of the game. Also, you're not really a party pooper.");
			shareEverything = AddConfigEntry("Emote Settings", "ShareEverything", defaultValue: true, "[Host only] This setting will be ignored if \"I am a Party Pooper\" is enabled. If this setting is set to false, emotes in the store will be different for each player. Unlocking emotes will only unlock for the player that purchased the emote. Each player will have their own emote credits. The amount of emote credits that each player will receive will NOT be reduced.");
			syncUnsharedEmotes = AddConfigEntry("Emote Settings", "CanSyncUnsharedEmotes", defaultValue: true, "[Host only] Only applies if ShareEverything is false. If set to true, players will be able to sync emotes with other players, even if they do not have the emote being performed unlocked.");
			enableMovingWhileEmoting = AddConfigEntry("Emote Settings", "CanMoveWhileEmoting", defaultValue: false, "[Host only] If set to true, rotating while emoting will be automatic. To cancel an emote, you will press the vanilla menu button.");
			disableRaritySystem = AddConfigEntry("Emote Settings", "DisableRaritySystem", defaultValue: false, "[Host only] If true, every emote will have the same likelyhood of appearing in the emote store.");
			basePriceEmoteRaritySystemDisabled = AddConfigEntry("Emote Settings", "BasePriceEmote - Rarity System Disabled", 100, "[Host only] Base price of emotes if the rarity system is disabled.");
			startingEmoteCredits = AddConfigEntry("Emote Settings", "StartingEmoteCredits", 100, "[Host only] The number of emote credits you start each game with.");
			addEmoteCreditsMultiplier = AddConfigEntry("Emote Settings", "AddEmoteCreditsMultiplier", 0.5f, "[Host only] You gain emote credits based off this multiplier of normal group credits earned. Example: If set to the default, 0.5, and you earn 200 group credits, you will also gain 100 emote credits.");
			purchaseEmotesWithDefaultCurrency = AddConfigEntry("Emote Settings", "PurchaseEmotesWithDefaultCredits", defaultValue: true, "[Host only] Setting this to true will allow you to purchase emotes with normal group credits once you run out of emote credits. This setting will automatically be disabled if ShareEverything is false.");
			priceMultiplierEmotesStore = AddConfigEntry("Emote Settings", "PriceMultiplierEmotesStore", 1f, "[Host only] Price multiplier for emotes in the store. Only applies if UnlockEverythingAtStart is false.");
			basePriceEmoteTier0 = AddConfigEntry("Emote Settings", "PriceCommonEmote", 50, "[Host only] The base price of [common]emotes in the store.");
			basePriceEmoteTier1 = AddConfigEntry("Emote Settings", "PriceUncommonEmote", 100, "[Host only] The base price of [uncommon] emotes in the store.");
			basePriceEmoteTier2 = AddConfigEntry("Emote Settings", "PriceRareEmote", 200, "[Host only] The base price of [rare] emotes in the store.");
			basePriceEmoteTier3 = AddConfigEntry("Emote Settings", "PriceLegendaryEmote", 300, "[Host only] The base price of [legendary] emotes in the store.");
			numEmotesStoreRotation = AddConfigEntry("Emote Settings", "EmotesInStoreRotation", 6, "[Host only] The number of emotes that will be available at a time in the store. Only applies if UnlockEverythingAtStart is false.");
			rotationChanceEmoteTier0 = AddConfigEntry("Emote Settings", "RotationWeightCommonEmote", 0.55f, "[Host only] The likelyhood of [common] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier1 = AddConfigEntry("Emote Settings", "RotationWeightUncommonEmote", 0.35f, "[Host only] The likelyhood of [uncommon] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier2 = AddConfigEntry("Emote Settings", "RotationWeightRareEmote", 0.08f, "[Host only] The likelyhood of [rare] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier3 = AddConfigEntry("Emote Settings", "RotationWeightLegendaryEmote", 0.02f, "[Host only] The likelyhood of [legendary] emotes appearing (per slot) in the store rotation.");
			enableMaskedEnemiesEmoting = AddConfigEntry("MaskedEnemyEmotes - Beta", "EnableMaskedEnemiesEmoting", defaultValue: true, "[Host only] Enabling this alone does not change the behaviour of the Masked Enemies, and shouldn't conflict with other mods.");
			maskedEnemiesEmoteChanceOnEncounter = AddConfigEntry("MaskedEnemyEmotes - Beta", "EmoteChanceOnEncounter", 0.25f, "[Host only] Chance per encounter with a Masked Enemy, for them to perform an emote. Use values between 0 and 1.");
			maskedEnemiesAlwaysEmoteOnFirstEncounter = AddConfigEntry("MaskedEnemyEmotes - Beta", "AlwaysEmoteOnFirstEncounter", defaultValue: true, "[Host only] This will force the first encounter (for each player) with a Masked Enemy to trigger an emote, regardless of EmoteChanceOnEncounter.");
			enableSyncingEmotesWithMaskedEnemies = AddConfigEntry("MaskedEnemyEmotes - Beta", "EnableSyncingEmotesWithMaskedEnemies", defaultValue: true, "[Client-side] Enabling this will allow you to sync emotes with Masked Enemies. This config is mainly here to disable in case of strange issues.");
			maskedEnemyEmoteRandomDelay = AddConfigEntry("MaskedEnemyEmotes - Beta", "RandomEmoteDelay", "1.5,2.0", "[Host only] Random range at which Masked Enemies will delay before performing an emote. These values could be raised a bit if OverrideStopAndStareDuration is enabled, otherwise, you may run into emotes ending quickly.");
			overrideStopAndStareDuration = AddConfigEntry("MaskedEnemyEmotes - Beta", "OverrideStopAndStareDuration", defaultValue: true, "[Host only] Enabling this will allow this mod to extend the stop and stare duration for longer emotes. If disabled, emotes may end very quickly. Disable this setting if you run into mod conflicts.");
			maskedEnemyEmoteRandomDuration = AddConfigEntry("MaskedEnemyEmotes - Beta", "RandomEmoteDuration", "2.0,4.0", "[Host only] Random range on how long Masked Enemies will emote for. This will extend the Masked Enemies' stop and stare duration by this amount. Only applies if OverrideStopAndStareDuration is true.");
			disableEmotesForSelf = AddConfigEntry("Emote Radial Menu", "DisableEmotingForSelf", defaultValue: false, "Disabling this will not convert your player's animator controller to an AnimatorOverrideController, and you will not be able to perform custom emotes. Disable this in case of specific mod conflicts. You will still be able to see other players emoting.");
			openEmoteMenuKeybind = AddConfigEntry("Emote Radial Menu", "OpenEmoteMenuKeybind", "<Keyboard>/backquote", "NOTE: This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)");
			rotateCharacterInEmoteKeybind = AddConfigEntry("Emote Radial Menu", "RotateCharacterInEmoteKeybind", "<Keyboard>/leftAlt", "Keybind to hold to rotate character while performing a custom emote. NOTE: This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)");
			toggleRotateCharacterInEmote = AddConfigEntry("Emote Radial Menu", "ToggleRotateCharacterInEmote", defaultValue: false, "If true, rotating character while emoting will be toggled, instead of rotating while holding the hotkey.");
			toggleEmoteMenu = AddConfigEntry("Emote Radial Menu", "ToggleEmoteMenu", defaultValue: false, "If set to false, the emote menu will open upon pressing the related keybind, and close upon releasing, and will play the currently hovered emote.");
			reverseEmoteWheelScrollDirection = AddConfigEntry("Emote Radial Menu", "ReverseEmoteWheelScrollDirection", defaultValue: false, "Reverses the page swapping direction in your emote when scrolling.");
			emoteNameColorTier0 = AddConfigEntry("Accessibility", "CommonEmoteNameColor", "#00FF00", "The color of the [common] emote name in the terminal.");
			emoteNameColorTier1 = AddConfigEntry("Accessibility", "UncommonEmoteNameColor", "#2828FF", "The color of the [uncommon] emote name in the terminal.");
			emoteNameColorTier2 = AddConfigEntry("Accessibility", "RareEmoteNameColor", "#AA00EE", "The color of the [rare] emote name in the terminal.");
			emoteNameColorTier3 = AddConfigEntry("Accessibility", "LegendaryEmoteNameColor", "#FF2222", "The color of the [legendary] emote name in the terminal.");
			float value = rotationChanceEmoteTier0.Value;
			value += rotationChanceEmoteTier1.Value;
			value += rotationChanceEmoteTier2.Value;
			value += rotationChanceEmoteTier3.Value;
			if (value != 1f && value != 0f)
			{
				ConfigEntry<float> obj = rotationChanceEmoteTier0;
				obj.Value /= value;
				ConfigEntry<float> obj2 = rotationChanceEmoteTier1;
				obj2.Value /= value;
				ConfigEntry<float> obj3 = rotationChanceEmoteTier2;
				obj3.Value /= value;
				ConfigEntry<float> obj4 = rotationChanceEmoteTier3;
				obj4.Value /= value;
				((BaseUnityPlugin)Plugin.instance).Config.Save();
			}
			TryRemoveOldConfigSettings();
			ConfigSync.BuildDefaultConfigSync();
		}

		public static ConfigEntry<T> AddConfigEntry<T>(string section, string name, T defaultValue, string description)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)Plugin.instance).Config.Bind<T>(section, name, defaultValue, description);
			currentConfigEntries.Add(((ConfigEntryBase)val).Definition.Key, (ConfigEntryBase)(object)val);
			return val;
		}

		public static string GetDisplayName(string key)
		{
			try
			{
				if (key.Length <= 1)
				{
					return key;
				}
				int num = key.IndexOf(">/");
				key = ((num >= 0) ? key.Substring(num + 2) : key);
				string text = key.ToLower();
				text = text.Replace("leftalt", "Alt");
				text = text.Replace("rightalt", "Alt");
				text = text.Replace("leftctrl", "Ctrl");
				text = text.Replace("rightctrl", "Ctrl");
				text = text.Replace("leftshift", "Shift");
				text = text.Replace("rightshift", "Shift");
				text = text.Replace("leftbutton", "LMB");
				text = text.Replace("rightbutton", "RMB");
				text = text.Replace("middlebutton", "MMB");
				text = text.Replace("lefttrigger", "LT");
				text = text.Replace("righttrigger", "RT");
				text = text.Replace("leftshoulder", "LB");
				text = text.Replace("rightshoulder", "RB");
				text = text.Replace("leftstickpress", "LS");
				text = text.Replace("rightstickpress", "RS");
				text = text.Replace("backquote", "`");
				try
				{
					text = char.ToUpper(text[0]) + text.Substring(1);
				}
				catch
				{
				}
				return text;
			}
			catch
			{
				return "";
			}
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
}
namespace TooManyEmotes.Input
{
	internal class InputUtilsCompat
	{
		internal static InputActionAsset Asset => IngameKeybinds.GetAsset();

		internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils");

		public static InputAction OpenEmoteMenuHotkey => IngameKeybinds.Instance.OpenEmoteMenuHotkey;

		public static InputAction RotateCharacterEmoteHotkey => IngameKeybinds.Instance.RotateCharacterEmoteHotkey;

		public static InputAction FavoriteEmoteHotkey => IngameKeybinds.Instance.FavoriteEmoteHotkey;
	}
	internal class IngameKeybinds : LcInputActions
	{
		internal static IngameKeybinds Instance = new IngameKeybinds();

		[InputAction("<Keyboard>/backquote", Name = "[TooManyEmotes]\nOpen Emote Menu")]
		public InputAction OpenEmoteMenuHotkey { get; set; }

		[InputAction("<Keyboard>/leftAlt", Name = "[TooManyEmotes]\nRotate Character in Emote")]
		public InputAction RotateCharacterEmoteHotkey { get; set; }

		[InputAction("<Mouse>/middleButton", Name = "[TooManyEmotes]\nFavorite Emote")]
		public InputAction FavoriteEmoteHotkey { get; set; }

		internal static InputActionAsset GetAsset()
		{
			return ((LcInputActions)Instance).Asset;
		}
	}
	[HarmonyPatch]
	public static class Keybinds
	{
		public static InputActionAsset Asset;

		public static InputActionMap ActionMap;

		public static InputAction OpenEmoteMenuAction;

		public static InputAction RotatePlayerEmoteAction;

		public static InputAction FavoriteEmoteAction;

		public static InputAction QuickEmoteFavorite1Action;

		public static InputAction QuickEmoteFavorite2Action;

		public static InputAction QuickEmoteFavorite3Action;

		public static InputAction QuickEmoteFavorite4Action;

		public static InputAction QuickEmoteFavorite5Action;

		public static InputAction QuickEmoteFavorite6Action;

		public static InputAction QuickEmoteFavorite7Action;

		public static InputAction QuickEmoteFavorite8Action;

		public static InputAction SelectEmoteUIAction;

		public static InputAction RawScrollAction;

		public static bool holdingRotatePlayerModifier;

		public static bool toggledRotating;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static void InitKeybinds()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			Plugin.Log("Initializing custom emote hotkeys.");
			Plugin.Log("InputUtilsLoaded: " + InputUtilsCompat.Enabled);
			if (InputUtilsCompat.Enabled)
			{
				Asset = InputUtilsCompat.Asset;
				ActionMap = Asset.actionMaps[0];
				OpenEmoteMenuAction = InputUtilsCompat.OpenEmoteMenuHotkey;
				RotatePlayerEmoteAction = InputUtilsCompat.RotateCharacterEmoteHotkey;
				FavoriteEmoteAction = InputUtilsCompat.FavoriteEmoteHotkey;
				SelectEmoteUIAction = new InputAction("TooManyEmotes.SelectEmote", (InputActionType)0, "<Mouse>/leftButton", "Press", (string)null, (string)null);
				RawScrollAction = new InputAction("TooManyEmotes.ScrollEmoteMenu", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null);
			}
			else
			{
				Asset = new InputActionAsset();
				ActionMap = new InputActionMap("TooManyEmotes");
				InputActionSetupExtensions.AddActionMap(Asset, ActionMap);
				OpenEmoteMenuAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.OpenEmoteMenu", (InputActionType)0, ConfigSettings.openEmoteMenuKeybind.Value, "Press", (string)null, (string)null, (string)null);
				RotatePlayerEmoteAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.RotatePlayerEmote", (InputActionType)0, ConfigSettings.rotateCharacterInEmoteKeybind.Value, "Press", (string)null, (string)null, (string)null);
				FavoriteEmoteAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.FavoriteEmote", (InputActionType)0, "<Mouse>/middleButton", "Press", (string)null, (string)null, (string)null);
				SelectEmoteUIAction = new InputAction("TooManyEmotes.SelectEmote", (InputActionType)0, "<Mouse>/leftButton", "Press", (string)null, (string)null);
				RawScrollAction = new InputAction("TooManyEmotes.ScrollEmoteMenu", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable()
		{
			Asset.Enable();
			OpenEmoteMenuAction.performed += OnPressOpenEmoteMenu;
			OpenEmoteMenuAction.canceled += OnPressOpenEmoteMenu;
			FavoriteEmoteAction.performed += OnFavoriteEmote;
			RotatePlayerEmoteAction.performed += OnUpdateRotatePlayerEmoteModifier;
			RotatePlayerEmoteAction.canceled += OnUpdateRotatePlayerEmoteModifier;
			SelectEmoteUIAction.Enable();
			SelectEmoteUIAction.performed += OnSelectEmoteUI;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable()
		{
			Asset.Disable();
			OpenEmoteMenuAction.performed -= OnPressOpenEmoteMenu;
			OpenEmoteMenuAction.canceled -= OnPressOpenEmoteMenu;
			FavoriteEmoteAction.performed -= OnFavoriteEmote;
			RotatePlayerEmoteAction.performed -= OnUpdateRotatePlayerEmoteModifier;
			RotatePlayerEmoteAction.canceled -= OnUpdateRotatePlayerEmoteModifier;
			SelectEmoteUIAction.Disable();
			SelectEmoteUIAction.performed -= OnSelectEmoteUI;
		}

		private static void OnPressOpenEmoteMenu(CallbackContext context)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayerController == (Object)null || ConfigSettings.disableEmotesForSelf.Value)
			{
				return;
			}
			if (!EmoteMenuManager.isMenuOpen)
			{
				if (((CallbackContext)(ref context)).performed && EmoteMenuManager.CanOpenEmoteMenu())
				{
					EmoteMenuManager.OpenEmoteMenu();
				}
			}
			else if (ConfigSettings.toggleEmoteMenu.Value)
			{
				if (((CallbackContext)(ref context)).performed)
				{
					EmoteMenuManager.CloseEmoteMenu();
				}
			}
			else if (((CallbackContext)(ref context)).canceled)
			{
				if (EmoteMenuManager.hoveredEmoteIndex != -1)
				{
					PerformEmoteLocal(context);
				}
				EmoteMenuManager.CloseEmoteMenu();
			}
		}

		private static void OnSelectEmoteUI(CallbackContext context)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen)
			{
				if (EmoteMenuManager.hoveredLoadoutUIIndex != -1 && EmoteMenuManager.hoveredLoadoutUIIndex != EmoteMenuManager.currentLoadoutIndex)
				{
					EmoteMenuManager.SetCurrentEmoteLoadout(EmoteMenuManager.hoveredLoadoutUIIndex);
				}
				else if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count)
				{
					PerformEmoteLocal(context);
					EmoteMenuManager.CloseEmoteMenu();
				}
			}
		}

		public static void PerformEmoteLocal(CallbackContext context)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count && !ConfigSettings.disableEmotesForSelf.Value)
			{
				UnlockableEmote unlockableEmote = EmoteMenuManager.currentLoadoutEmotesList[EmoteMenuManager.hoveredEmoteIndex];
				if (unlockableEmote != null)
				{
					localPlayerController.PerformEmote(context, -(unlockableEmote.emoteId + 1));
				}
			}
		}

		public static void OnFavoriteEmote(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen && EmoteMenuManager.hoveredEmoteUIIndex != -1 && EmoteMenuManager.previewingEmote != null)
			{
				EmoteMenuManager.ToggleFavoriteHoveredEmote();
			}
		}

		public static void OnQuickEmote(CallbackContext context, int quickEmoteNumber)
		{
		}

		public static void OnUpdateRotatePlayerEmoteModifier(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || ConfigSettings.disableEmotesForSelf.Value || ConfigSync.instance.syncEnableMovingWhileEmoting)
			{
				return;
			}
			if (((CallbackContext)(ref context)).performed)
			{
				if (ConfigSettings.toggleRotateCharacterInEmote.Value)
				{
					toggledRotating = !toggledRotating;
				}
				else
				{
					holdingRotatePlayerModifier = true;
				}
			}
			else if (((CallbackContext)(ref context)).canceled && !ConfigSettings.toggleRotateCharacterInEmote.Value)
			{
				holdingRotatePlayerModifier = false;
			}
		}
	}
}
namespace TooManyEmotes.Networking
{
	[Serializable]
	[HarmonyPatch]
	public class ConfigSync
	{
		public static bool isSynced;

		public static ConfigSync defaultConfig;

		public static ConfigSync instance;

		public bool syncUnlockEverything;

		public bool syncShareEverything;

		public bool syncSyncUnsharedEmotes;

		public bool syncEnableMovingWhileEmoting;

		public bool syncDisableRaritySystem;

		public int syncStartingEmoteCredits;

		public float syncAddEmoteCreditsMultiplier;

		public bool syncPurchaseEmotesWithDefaultCurrency;

		public float syncPriceMultiplierEmotesStore;

		public int syncBasePriceEmoteTier0;

		public int syncBasePriceEmoteTier1;

		public int syncBasePriceEmoteTier2;

		public int syncBasePriceEmoteTier3;

		public int syncNumEmotesStoreRotation;

		public float syncRotationChanceEmoteTier0;

		public float syncRotationChanceEmoteTier1;

		public float syncRotationChanceEmoteTier2;

		public float syncRotationChanceEmoteTier3;

		public bool syncEnableMaskedEnemiesEmoting;

		public float syncMaskedEnemiesEmoteChanceOnEncounter;

		public bool syncMaskedEnemiesAlwaysEmoteOnFirstEncounter;

		public bool syncOverrideStopAndStareDuration;

		public float syncMaskedEnemyEmoteRandomDelayMin;

		public float syncMaskedEnemyEmoteRandomDelayMax;

		public float syncMaskedEnemyEmoteRandomDurationMin;

		public float syncMaskedEnemyEmoteRandomDurationMax;

		public static Vector2 syncMaskedEnemyEmoteRandomDelay;

		public static Vector2 syncMaskedEnemyEmoteRandomDuration;

		public static HashSet<ulong> syncedClients;

		public ConfigSync()
		{
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			syncUnlockEverything = ConfigSettings.unlockEverything.Value;
			syncShareEverything = ConfigSettings.shareEverything.Value;
			syncSyncUnsharedEmotes = ConfigSettings.syncUnsharedEmotes.Value;
			syncEnableMovingWhileEmoting = ConfigSettings.enableMovingWhileEmoting.Value;
			syncDisableRaritySystem = ConfigSettings.disableRaritySystem.Value;
			syncStartingEmoteCredits = ConfigSettings.startingEmoteCredits.Value;
			syncAddEmoteCreditsMultiplier = ConfigSettings.addEmoteCreditsMultiplier.Value;
			syncPurchaseEmotesWithDefaultCurrency = ConfigSettings.purchaseEmotesWithDefaultCurrency.Value;
			syncPriceMultiplierEmotesStore = ConfigSettings.priceMultiplierEmotesStore.Value;
			syncNumEmotesStoreRotation = ConfigSettings.numEmotesStoreRotation.Value;
			syncRotationChanceEmoteTier0 = ConfigSettings.rotationChanceEmoteTier0.Value;
			syncRotationChanceEmoteTier1 = ConfigSettings.rotationChanceEmoteTier1.Value;
			syncRotationChanceEmoteTier2 = ConfigSettings.rotationChanceEmoteTier2.Value;
			syncRotationChanceEmoteTier3 = ConfigSettings.rotationChanceEmoteTier3.Value;
			syncEnableMaskedEnemiesEmoting = ConfigSettings.enableMaskedEnemiesEmoting.Value;
			syncMaskedEnemiesEmoteChanceOnEncounter = ConfigSettings.maskedEnemiesEmoteChanceOnEncounter.Value;
			syncMaskedEnemiesAlwaysEmoteOnFirstEncounter = ConfigSettings.maskedEnemiesAlwaysEmoteOnFirstEncounter.Value;
			syncOverrideStopAndStareDuration = ConfigSettings.overrideStopAndStareDuration.Value;
			syncMaskedEnemyEmoteRandomDelay = ParseVector2FromString(ConfigSettings.maskedEnemyEmoteRandomDelay.Value);
			syncMaskedEnemyEmoteRandomDelayMin = syncMaskedEnemyEmoteRandomDelay.x;
			syncMaskedEnemyEmoteRandomDelayMax = syncMaskedEnemyEmoteRandomDelay.y;
			syncMaskedEnemyEmoteRandomDuration = ParseVector2FromString(ConfigSettings.maskedEnemyEmoteRandomDuration.Value);
			syncMaskedEnemyEmoteRandomDurationMin = syncMaskedEnemyEmoteRandomDuration.x;
			syncMaskedEnemyEmoteRandomDurationMax = syncMaskedEnemyEmoteRandomDuration.y;
			if (syncUnlockEverything)
			{
				syncShareEverything = true;
			}
			if (ConfigSettings.disableRaritySystem.Value)
			{
				syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
			}
			else
			{
				syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteTier0.Value;
				syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteTier1.Value;
				syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteTier2.Value;
				syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteTier3.Value;
			}
		}

		public Vector2 ParseVector2FromString(string str)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Vector2 result = Vector2.zero;
			try
			{
				string[] array = str.Split(new char[1] { ',' });
				if (float.TryParse(array[0].Trim(new char[1] { ' ' }), out var result2) && float.TryParse(array[1].Trim(new char[1] { ' ' }), out var result3))
				{
					result = new Vector2(Mathf.Min(Mathf.Abs(result2), Mathf.Abs(result3)), Mathf.Max(Mathf.Abs(result2), Mathf.Abs(result3)));
				}
				return result;
			}
			catch
			{
			}
			return Vector2.zero;
		}

		public static void BuildDefaultConfigSync()
		{
			defaultConfig = new ConfigSync();
			instance = new ConfigSync();
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		public static void ResetValues()
		{
			isSynced = false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init(PlayerControllerB __instance)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			if (isSynced)
			{
				return;
			}
			isSynced = NetworkManager.Singleton.IsServer;
			EmoteSyncManager.isSynced = false;
			EmoteSyncManager.requestedSync = false;
			if (NetworkManager.Singleton.IsServer)
			{
				syncedClients = new HashSet<ulong>();
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncServerRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncServerRpc));
				if (!instance.syncUnlockEverything)
				{
					return;
				}
				{
					foreach (UnlockableEmote allUnlockableEmote in StartOfRoundPatcher.allUnlockableEmotes)
					{
						StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote);
					}
					return;
				}
			}
			foreach (UnlockableEmote allUnlockableEmote2 in StartOfRoundPatcher.allUnlockableEmotes)
			{
				StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote2);
			}
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncClientRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncClientRpc));
			RequestConfigSync();
		}

		public static void RequestConfigSync()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Requesting config sync from server");
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncServerRpc", 0uL, val, (NetworkDelivery)3);
			}
			else
			{
				Plugin.LogError("Failed to send unlocked emote update to server.");
			}
		}

		private static void OnRequestConfigSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsServer)
			{
				Plugin.Log("Receiving config sync request from client: " + clientId);
				syncedClients.Add(clientId);
				EmoteSyncManager.syncedClients.Remove(clientId);
				byte[] array = SerializeConfigToByteArray(instance);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4 + array.Length, (Allocator)2, -1);
				int num = array.Length;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncClientRpc", clientId, val, (NetworkDelivery)3);
			}
		}

		private static void OnRequestConfigSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient)
			{
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.Log("Receiving config sync from server.");
				byte[] data = new byte[num];
				((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
				instance = DeserializeFromByteArray(data);
				if (instance.syncUnlockEverything)
				{
					instance.syncShareEverything = true;
				}
				syncMaskedEnemyEmoteRandomDelay = new Vector2(instance.syncMaskedEnemyEmoteRandomDelayMin, instance.syncMaskedEnemyEmoteRandomDelayMax);
				syncMaskedEnemyEmoteRandomDuration = new Vector2(instance.syncMaskedEnemyEmoteRandomDurationMin, instance.syncMaskedEnemyEmoteRandomDurationMax);
				isSynced = true;
				if (StartOfRoundPatcher.allUnlockableEmotes != null && StartOfRoundPatcher.unlockedEmotes != null)
				{
					StartOfRoundPatcher.ResetProgressLocal();
					if (instance.syncUnlockEverything)
					{
						StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.allUnlockableEmotes);
					}
					else
					{
						StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.complementaryEmotes);
					}
					StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes();
				}
			}
			else
			{
				Plugin.LogError("Error receiving sync from server.");
			}
		}

		public static byte[] SerializeConfigToByteArray(ConfigSync config)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			MemoryStream memoryStream = new MemoryStream();
			binaryFormatter.Serialize(memoryStream, config);
			return memoryStream.ToArray();
		}

		public static ConfigSync DeserializeFromByteArray(byte[] data)
		{
			MemoryStream serializationStream = new MemoryStream(data);
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			return (ConfigSync)binaryFormatter.Deserialize(serializationStream);
		}
	}
	[HarmonyPatch]
	public static class EmoteSyncManager
	{
		public static bool requestedSync;

		public static bool isSynced;

		public static HashSet<ulong> syncedClients;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		public static void ResetValues()
		{
			isSynced = false;
			requestedSync = false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			isSynced = NetworkManager.Singleton.IsServer;
			requestedSync = NetworkManager.Singleton.IsServer;
			if (NetworkManager.Singleton.IsServer)
			{
				syncedClients = new HashSet<ulong>();
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncServerRpc", new HandleNamedMessageDelegate(OnRequestSyncServerRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteServerRpc", new HandleNamedMessageDelegate(OnUnlockEmoteServerRpc));
			}
			else
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncClientRpc", new HandleNamedMessageDelegate(OnRequestSyncClientRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteClientRpc", new HandleNamedMessageDelegate(OnUnlockEmoteClientRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRotateEmotesClientRpc", new HandleNamedMessageDelegate(RotateEmoteSelectionClientRpc));
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		public static void RequestSyncAfterConfigUpdate(PlayerControllerB __instance)
		{
			if (!isSynced && !requestedSync && ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController)
			{
				SendSyncRequest();
				requestedSync = true;
			}
		}

		public static void SendSyncRequest()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Sending sync request to server.");
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestSyncServerRpc", 0uL, val, (NetworkDelivery)3);
			}
		}

		private static void OnRequestSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				Plugin.Log("Receiving sync request from client: " + clientId);
				ServerSendSyncToClient(clientId);
			}
		}

		public static void ServerSendSyncToClient(ulong clientId)
		{
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer || !ConfigSync.syncedClients.Contains(clientId))
			{
				return;
			}
			PlayerControllerB playerController = null;
			StartOfRoundPatcher.TryGetPlayerByClientId(clientId, out playerController);
			if ((Object)(object)playerController != (Object)null)
			{
				if (!StartOfRoundPatcher.unlockedEmotesByPlayer.ContainsKey(playerController.playerUsername))
				{
					StartOfRoundPatcher.unlockedEmotesByPlayer.Add(playerController.playerUsername, new List<UnlockableEmote>());
				}
				if (!TerminalPatcher.currentEmoteCreditsByPlayer.ContainsKey(playerController.playerUsername))
				{
					TerminalPatcher.currentEmoteCreditsByPlayer.Add(playerController.playerUsername, ConfigSync.instance.syncStartingEmoteCredits);
				}
			}
			List<UnlockableEmote> list = StartOfRoundPatcher.unlockedEmotes;
			int num = TerminalPatcher.currentEmoteCredits;
			if (!ConfigSync.instance.syncUnlockEverything && !ConfigSync.instance.syncShareEverything)
			{
				if ((Object)(object)playerController != (Object)null)
				{
					if (StartOfRoundPatcher.unlockedEmotesByPlayer.TryGetValue(playerController.playerUsername, out var value))
					{
						Plugin.Log("Loading " + value.Count + " unlocked emotes for player: " + playerController.playerUsername);
						list = value;
					}
					if (TerminalPatcher.currentEmoteCreditsByPlayer.TryGetValue(playerController.playerUsername, out var value2))
					{
						Plugin.Log("Loading " + value2 + " emote credits for player: " + playerController.playerUsername);
						num = value2;
					}
				}
				else
				{
					Plugin.LogError("Error loading custom emotes for player. Player with id: " + clientId + " does not exist?");
					list = StartOfRoundPatcher.complementaryEmotes;
					num = ConfigSync.instance.syncStartingEmoteCredits;
				}
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12 + 4 * list.Count, (Allocator)2, -1);
			((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
			int count = list.Count;
			((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref count, default(ForPrimitives));
			for (int i = 0; i < list.Count; i++)
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref list[i].emoteId, default(ForPrimitives));
			}
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestSyncClientRpc", clientId, val, (NetworkDelivery)3);
		}

		private static void OnRequestSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || !ConfigSync.isSynced)
			{
				return;
			}
			isSynced = true;
			if (((FastBufferReader)(ref reader)).TryBeginRead(12))
			{
				StartOfRoundPatcher.ResetProgressLocal();
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.currentEmoteCredits, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
				TerminalPatcher.RotateNewEmoteSelection();
				Plugin.Log("Receiving sync from server. CurrentEmoteCredits: " + TerminalPatcher.currentEmoteCredits + " EmoteStoreSeed: " + TerminalPatcher.emoteStoreSeed + " NumEmotes: " + num);
				if (num <= 0)
				{
					if (num == -1)
					{
						StartOfRoundPatcher.ResetEmotesLocal();
					}
				}
				else
				{
					if (!((FastBufferReader)(ref reader)).TryBeginRead(4 * num))
					{
						Plugin.LogError("Error receiving emotes sync from server.");
						return;
					}
					int emoteId = default(int);
					for (int i = 0; i < num; i++)
					{
						((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
					}
				}
				isSynced = true;
				Plugin.Log("Received sync from server.");
			}
			else
			{
				Plugin.LogError("Error receiving sync from server.");
			}
		}

		public static void SendOnUnlockEmoteUpdate(int emoteId, int newEmoteCredits = -1)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
			Plugin.Log("Sending unlocked emote update to server. Emote id: " + emoteId);
			((FastBufferWriter)(ref val)).WriteValue<int>(ref newEmoteCredits, default(ForPrimitives));
			int num = 1;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref num, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValue<int>(ref emoteId, default(ForPrimitives));
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnUnlockEmoteServerRpc", 0uL, val, (NetworkDelivery)3);
		}

		public static void SendOnUnlockEmoteUpdateMulti(int newEmoteCredits = -1)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(8 + 4 * StartOfRoundPatcher.unlockedEmotes.Count, (Allocator)2, -1);
			Plugin.Log("Sending all unlocked emotes update to server.");
			((FastBufferWriter)(ref val)).WriteValue<int>(ref newEmoteCredits, default(ForPrimitives));
			int count = StartOfRoundPatcher.unlockedEmotes.Count;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
			foreach (UnlockableEmote unlockedEmote in StartOfRoundPatcher.unlockedEmotes)
			{
				((FastBufferWriter)(ref val)).WriteValue<int>(ref unlockedEmote.emoteId, default(ForPrimitives));
			}
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnUnlockEmoteServerRpc", 0uL, val, (NetworkDelivery)3);
		}

		private static void OnUnlockEmoteServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_001f: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
			PlayerControllerB playerController = null;
			StartOfRoundPatcher.TryGetPlayerByClientId(clientId, out playerController);
			if (num != -1)
			{
				if (!ConfigSync.instance.syncShareEverything && clientId != 0)
				{
					if ((Object)(object)playerController != (Object)null)
					{
						TerminalPatcher.currentEmoteCreditsByPlayer[playerController.playerUsername] = num;
					}
				}
				else
				{
					TerminalPatcher.currentEmoteCredits = num;
				}
			}
			Plugin.Log("Receiving unlocked emote update from client for " + num2 + " emotes.");
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(16 + 4 * num2, (Allocator)2, -1);
			((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref clientId, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TerminalPatcher.currentEmoteCredits, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num2, default(ForPrimitives));
			if (((FastBufferReader)(ref reader)).TryBeginRead(4 * num2))
			{
				int emoteId = default(int);
				for (int i = 0; i < num2; i++)
				{
					((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref emoteId, default(ForPrimitives));
					if (!ConfigSync.instance.syncShareEverything && clientId != 0)
					{
						if ((Object)(object)playerController != (Object)null)
						{
							StartOfRoundPatcher.UnlockEmoteLocal(emoteId, playerController.playerUsername);
						}
					}
					else
					{
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
					}
				}
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("TooManyEmotes-OnUnlockEmoteClientRpc", val, (NetworkDelivery)3);
			}
			else
			{
				Plugin.LogError("Failed to receive unlocked emote updates from client. Expected updates: " + num2);
			}
		}

		private static void OnUnlockEmoteClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
			{
				return;
			}
			ulong clientId2 = default(ulong);
			((FastBufferReader)(ref reader)).ReadValue<ulong>(ref clientId2, default(ForPrimitives));
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
			StartOfRoundPatcher.TryGetPlayerByClientId(clientId2, out var playerController);
			if (!ConfigSync.instance.syncShareEverything && (Object)(object)playerController == (Object)null)
			{
				return;
			}
			if (num != -1)
			{
				if (!ConfigSync.instance.syncShareEverything)
				{
					TerminalPatcher.currentEmoteCreditsByPlayer[playerController.playerUsername] = num;
				}
				else
				{
					TerminalPatcher.currentEmoteCredits = num;
				}
			}
			if (((FastBufferReader)(ref reader)).TryBeginRead(4 * num2))
			{
				int emoteId = default(int);
				for (int i = 0; i < num2; i++)
				{
					((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
					Plugin.Log("Receiving unlocked emote update from server. Emote id: " + emoteId);
					if (ConfigSync.instance.syncShareEverything)
					{
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
					}
					else
					{
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId, playerController.playerUsername);
					}
				}
			}
			else
			{
				Plugin.LogError("Failed to receive unlocked emote updates from client. Expected updates: " + num2);
			}
		}

		public static void RotateEmoteSelectionServerRpc(int overrideSeed = 0)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
			{
				TerminalPatcher.emoteStoreSeed = ((overrideSeed == 0) ? Random.Range(0, 1000000000) : overrideSeed);
				TerminalPatcher.RotateNewEmoteSelection();
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("TooManyEmotes-OnRotateEmotesClientRpc", val, (NetworkDelivery)3);
			}
		}

		private static void RotateEmoteSelectionClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer && ((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				TerminalPatcher.RotateNewEmoteSelection();
			}
		}
	}
}
namespace TooManyEmotes.CompatibilityPatcher
{
	[HarmonyPatch]
	internal class MoreEmotesPatcher
	{
		public static bool loadedMoreEmotes;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPostfix]
		public static void ApplyPatch()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			if (!Plugin.IsModLoaded("MoreEmotes") || !Chainloader.PluginInfos.TryGetValue("MoreEmotes", out var value))
			{
				return;
			}
			Assembly assembly = ((object)value.Instance).GetType().Assembly;
			if (assembly != null)
			{
				Plugin.Log("Applying compatibility patch for More_Emotes");
				Type type = assembly.GetType("MoreEmotes.Patch.EmotePatch");
				FieldInfo field = type.GetField("local", BindingFlags.Static | BindingFlags.Public);
				RuntimeAnimatorController val = (RuntimeAnimatorController)field.GetValue(null);
				if ((Object)(object)val != (Object)null && !(val is AnimatorOverrideController))
				{
					field.SetValue(null, (object?)new AnimatorOverrideController(val));
				}
				FieldInfo field2 = type.GetField("others", BindingFlags.Static | BindingFlags.Public);
				RuntimeAnimatorController val2 = (RuntimeAnimatorController)field2.GetValue(null);
				if ((Object)(object)val2 != (Object)null && !(val2 is AnimatorOverrideController))
				{
					field2.SetValue(null, (object?)new AnimatorOverrideController(val2));
				}
			}
		}
	}
	[HarmonyPatch]
	internal class BetterEmotesPatcher
	{
		public static bool loadedBetterEmotes;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPostfix]
		public static void ApplyPatch()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be

mods/HGG-JigglePhysicsPlugin-1.1.2/JigglePhysicsPlugin.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.LowLevel;
using UnityEngine.PlayerLoop;
using UnityEngine.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("JigglePhysicsPlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("JigglePhysicsPlugin")]
[assembly: AssemblyTitle("JigglePhysicsPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace JigglePhysicsPlugin
{
	public static class CachedSphereCollider
	{
		private class DestroyListener : MonoBehaviour
		{
			private void OnDestroy()
			{
				_hasSphere = false;
			}
		}

		private static bool _hasSphere;

		private static SphereCollider _sphereCollider;

		public static void StartPass()
		{
			if (TryGet(out var collider))
			{
				((Collider)collider).enabled = true;
			}
		}

		public static void FinishedPass()
		{
			if (TryGet(out var collider))
			{
				((Collider)collider).enabled = false;
			}
		}

		public static bool TryGet(out SphereCollider collider)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if (_hasSphere)
			{
				collider = _sphereCollider;
				return true;
			}
			try
			{
				GameObject val = new GameObject("JiggleBoneSphereCollider", new Type[2]
				{
					typeof(SphereCollider),
					typeof(DestroyListener)
				})
				{
					hideFlags = (HideFlags)61
				};
				if (Application.isPlaying)
				{
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				_sphereCollider = val.GetComponent<SphereCollider>();
				collider = _sphereCollider;
				((Collider)collider).enabled = false;
				_hasSphere = true;
				return true;
			}
			catch
			{
				if ((Object)(object)_sphereCollider != (Object)null)
				{
					if (Application.isPlaying)
					{
						Object.Destroy((Object)(object)((Component)_sphereCollider).gameObject);
					}
					else
					{
						Object.DestroyImmediate((Object)(object)((Component)_sphereCollider).gameObject);
					}
				}
				_hasSphere = false;
				collider = null;
				throw;
			}
		}
	}
	public class JiggleBone
	{
		private readonly bool hasTransform;

		private readonly PositionSignal targetAnimatedBoneSignal;

		private Vector3 currentFixedAnimatedBonePosition;

		public readonly JiggleBone parent;

		private JiggleBone child;

		private Quaternion boneRotationChangeCheck;

		private Vector3 bonePositionChangeCheck;

		private Quaternion lastValidPoseBoneRotation;

		private float projectionAmount;

		private Vector3 lastValidPoseBoneLocalPosition;

		private float normalizedIndex;

		public readonly Transform transform;

		private readonly PositionSignal particleSignal;

		private Vector3 workingPosition;

		private Vector3? preTeleportPosition;

		private Vector3 extrapolatedPosition;

		private float GetLengthToParent()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (parent == null)
			{
				return 0.1f;
			}
			return Vector3.Distance(currentFixedAnimatedBonePosition, parent.currentFixedAnimatedBonePosition);
		}

		public JiggleBone(Transform transform, JiggleBone parent, float projectionAmount = 1f)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			this.transform = transform;
			this.parent = parent;
			this.projectionAmount = projectionAmount;
			Vector3 startPosition;
			if ((Object)(object)transform != (Object)null)
			{
				lastValidPoseBoneRotation = transform.localRotation;
				lastValidPoseBoneLocalPosition = transform.localPosition;
				startPosition = transform.position;
			}
			else
			{
				startPosition = GetProjectedPosition();
			}
			targetAnimatedBoneSignal = new PositionSignal(startPosition, Time.timeAsDouble);
			particleSignal = new PositionSignal(startPosition, Time.timeAsDouble);
			hasTransform = (Object)(object)transform != (Object)null;
			if (parent != null)
			{
				this.parent.child = this;
			}
		}

		public void CalculateNormalizedIndex()
		{
			int num = 0;
			JiggleBone jiggleBone = this;
			while (jiggleBone.parent != null)
			{
				jiggleBone = jiggleBone.parent;
				num++;
			}
			int num2 = 0;
			jiggleBone = this;
			while (jiggleBone.child != null)
			{
				jiggleBone = jiggleBone.child;
				num2++;
			}
			int num3 = num + num2;
			float num4 = (float)num / (float)num3;
			normalizedIndex = num4;
		}

		public void VerletPass(JiggleSettingsData jiggleSettings, Vector3 wind, double time)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			currentFixedAnimatedBonePosition = targetAnimatedBoneSignal.SamplePosition(time);
			if (parent == null)
			{
				workingPosition = currentFixedAnimatedBonePosition;
				particleSignal.SetPosition(workingPosition, time);
			}
			else
			{
				Vector3 localSpaceVelocity = particleSignal.GetCurrent() - particleSignal.GetPrevious() - (parent.particleSignal.GetCurrent() - parent.particleSignal.GetPrevious());
				workingPosition = NextPhysicsPosition(particleSignal.GetCurrent(), particleSignal.GetPrevious(), localSpaceVelocity, Time.fixedDeltaTime, jiggleSettings.gravityMultiplier, jiggleSettings.friction, jiggleSettings.airDrag);
				workingPosition += wind * (Time.fixedDeltaTime * jiggleSettings.airDrag);
			}
		}

		public void CollisionPreparePass(JiggleSettingsData jiggleSettings)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			workingPosition = ConstrainLengthBackwards(workingPosition, jiggleSettings.lengthElasticity * jiggleSettings.lengthElasticity * 0.5f);
		}

		public void ConstraintPass(JiggleSettingsData jiggleSettings)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (parent != null)
			{
				workingPosition = ConstrainAngle(workingPosition, jiggleSettings.angleElasticity * jiggleSettings.angleElasticity, jiggleSettings.elasticitySoften);
				workingPosition = ConstrainLength(workingPosition, jiggleSettings.lengthElasticity * jiggleSettings.lengthElasticity);
			}
		}

		public void CollisionPass(JiggleSettingsBase jiggleSettings, List<Collider> colliders)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (colliders.Count == 0 || !CachedSphereCollider.TryGet(out var collider))
			{
				return;
			}
			Vector3 val = default(Vector3);
			float num = default(float);
			foreach (Collider collider2 in colliders)
			{
				collider.radius = jiggleSettings.GetRadius(normalizedIndex);
				if (!(collider.radius <= 0f) && Physics.ComputePenetration((Collider)(object)collider, workingPosition, Quaternion.identity, collider2, ((Component)collider2).transform.position, ((Component)collider2).transform.rotation, ref val, ref num))
				{
					workingPosition += val * num;
				}
			}
		}

		public void SignalWritePosition(double time)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			particleSignal.SetPosition(workingPosition, time);
		}

		private Vector3 GetProjectedPosition()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = parent.transform.position;
			return parent.transform.TransformPoint(parent.GetParentTransform().InverseTransformPoint(position) * projectionAmount);
		}

		private Vector3 GetTransformPosition()
		{
			//IL_001f: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTransform)
			{
				return GetProjectedPosition();
			}
			return transform.position;
		}

		private Transform GetParentTransform()
		{
			if (parent != null)
			{
				return parent.transform;
			}
			return transform.parent;
		}

		private void CacheAnimationPosition()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTransform)
			{
				targetAnimatedBoneSignal.SetPosition(GetProjectedPosition(), Time.timeAsDouble);
				return;
			}
			targetAnimatedBoneSignal.SetPosition(transform.position, Time.timeAsDouble);
			lastValidPoseBoneRotation = transform.localRotation;
			lastValidPoseBoneLocalPosition = transform.localPosition;
		}

		private Vector3 ConstrainLengthBackwards(Vector3 newPosition, float elasticity)
		{
			//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_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			if (child == null)
			{
				return newPosition;
			}
			Vector3 val = newPosition - child.workingPosition;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.Lerp(newPosition, child.workingPosition + normalized * child.GetLengthToParent(), elasticity);
		}

		private Vector3 ConstrainLength(Vector3 newPosition, float elasticity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = newPosition - parent.workingPosition;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.Lerp(newPosition, parent.workingPosition + normalized * GetLengthToParent(), elasticity);
		}

		public void MatchAnimationInstantly()
		{
			//IL_0008: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			double timeAsDouble = Time.timeAsDouble;
			Vector3 transformPosition = GetTransformPosition();
			targetAnimatedBoneSignal.FlattenSignal(timeAsDouble, transformPosition);
			particleSignal.FlattenSignal(timeAsDouble, transformPosition);
		}

		public void PrepareTeleport()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			preTeleportPosition = GetTransformPosition();
		}

		public void FinishTeleport()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			if (!preTeleportPosition.HasValue)
			{
				MatchAnimationInstantly();
				return;
			}
			Vector3 transformPosition = GetTransformPosition();
			Vector3 val = transformPosition - preTeleportPosition.Value;
			targetAnimatedBoneSignal.FlattenSignal(Time.timeAsDouble, transformPosition);
			particleSignal.OffsetSignal(val);
			workingPosition += val;
		}

		private Vector3 ConstrainAngleBackward(Vector3 newPosition, float elasticity, float elasticitySoften)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (child == null || child.child == null)
			{
				return newPosition;
			}
			Vector3 val = child.child.currentFixedAnimatedBonePosition - child.currentFixedAnimatedBonePosition;
			Vector3 val2 = child.child.workingPosition - child.workingPosition;
			Quaternion val3 = Quaternion.FromToRotation(val, val2);
			Vector3 val4 = newPosition - child.workingPosition;
			Vector3 val5 = val3 * val4;
			Debug.DrawLine(newPosition, child.workingPosition + val5, Color.cyan);
			float num = Vector3.Distance(newPosition, child.workingPosition + val5);
			num /= child.GetLengthToParent();
			num = Mathf.Clamp01(num);
			num = Mathf.Pow(num, elasticitySoften * 2f);
			return Vector3.Lerp(newPosition, child.workingPosition + val5, elasticity * num);
		}

		private Vector3 ConstrainAngle(Vector3 newPosition, float elasticity, float elasticitySoften)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTransform && projectionAmount == 0f)
			{
				return newPosition;
			}
			Vector3 val;
			Vector3 val2;
			if (parent.parent == null)
			{
				val = parent.currentFixedAnimatedBonePosition + (parent.currentFixedAnimatedBonePosition - currentFixedAnimatedBonePosition);
				val2 = val;
			}
			else
			{
				val2 = parent.parent.workingPosition;
				val = parent.parent.currentFixedAnimatedBonePosition;
			}
			Vector3 val3 = parent.currentFixedAnimatedBonePosition - val;
			Vector3 val4 = parent.workingPosition - val2;
			Quaternion val5 = Quaternion.FromToRotation(val3, val4);
			Vector3 val6 = currentFixedAnimatedBonePosition - val;
			Vector3 val7 = val5 * val6;
			float num = Vector3.Distance(newPosition, val2 + val7);
			num /= GetLengthToParent();
			num = Mathf.Clamp01(num);
			num = Mathf.Pow(num, elasticitySoften * 2f);
			return Vector3.Lerp(newPosition, val2 + val7, elasticity * num);
		}

		public static Vector3 NextPhysicsPosition(Vector3 newPosition, Vector3 previousPosition, Vector3 localSpaceVelocity, float deltaTime, float gravityMultiplier, float friction, float airFriction)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = deltaTime * deltaTime;
			Vector3 val = newPosition - previousPosition - localSpaceVelocity;
			return newPosition + val * (1f - airFriction) + localSpaceVelocity * (1f - friction) + Physics.gravity * (gravityMultiplier * num);
		}

		public void DebugDraw(Color simulateColor, Color targetColor, bool interpolated)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (parent != null)
			{
				if (interpolated)
				{
					Debug.DrawLine(extrapolatedPosition, parent.extrapolatedPosition, simulateColor, 0f, false);
				}
				else
				{
					Debug.DrawLine(workingPosition, parent.workingPosition, simulateColor, 0f, false);
				}
				Debug.DrawLine(currentFixedAnimatedBonePosition, parent.currentFixedAnimatedBonePosition, targetColor, 0f, false);
			}
		}

		public Vector3 DeriveFinalSolvePosition(Vector3 offset)
		{
			//IL_0002: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			extrapolatedPosition = offset + particleSignal.SamplePosition(Time.timeAsDouble);
			return extrapolatedPosition;
		}

		public Vector3 GetCachedSolvePosition()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return extrapolatedPosition;
		}

		public void PrepareBone()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (hasTransform)
			{
				if (boneRotationChangeCheck == transform.localRotation)
				{
					transform.localRotation = lastValidPoseBoneRotation;
				}
				if (bonePositionChangeCheck == transform.localPosition)
				{
					transform.localPosition = lastValidPoseBoneLocalPosition;
				}
			}
			CacheAnimationPosition();
		}

		public void OnDrawGizmos(JiggleSettingsBase jiggleSettings)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)transform != (Object)null && child != null && (Object)(object)child.transform != (Object)null)
			{
				Gizmos.DrawLine(transform.position, child.transform.position);
			}
			if ((Object)(object)transform != (Object)null && child != null && (Object)(object)child.transform == (Object)null)
			{
				Gizmos.DrawLine(transform.position, child.GetProjectedPosition());
			}
			if ((Object)(object)transform != (Object)null && (Object)(object)jiggleSettings != (Object)null)
			{
				Gizmos.DrawWireSphere(transform.position, jiggleSettings.GetRadius(normalizedIndex));
			}
			if ((Object)(object)transform == (Object)null && (Object)(object)jiggleSettings != (Object)null)
			{
				Gizmos.DrawWireSphere(GetProjectedPosition(), jiggleSettings.GetRadius(normalizedIndex));
			}
		}

		public void PoseBone(float blend)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (child != null)
			{
				Vector3 val = Vector3.Lerp(targetAnimatedBoneSignal.SamplePosition(Time.timeAsDouble), extrapolatedPosition, blend);
				Vector3 val2 = Vector3.Lerp(child.targetAnimatedBoneSignal.SamplePosition(Time.timeAsDouble), child.extrapolatedPosition, blend);
				if (parent != null)
				{
					transform.position = val;
				}
				Vector3 transformPosition = child.GetTransformPosition();
				Vector3 val3 = transformPosition - transform.position;
				Vector3 val4 = val2 - val;
				Quaternion val5 = Quaternion.FromToRotation(val3, val4);
				transform.rotation = val5 * transform.rotation;
			}
			if (hasTransform)
			{
				boneRotationChangeCheck = transform.localRotation;
				bonePositionChangeCheck = transform.localPosition;
			}
		}
	}
	[DefaultExecutionOrder(200)]
	public class JiggleRigBuilder : MonoBehaviour
	{
		[SerializeField]
		[Tooltip("The root bone from which an individual JiggleRig will be constructed. The JiggleRig encompasses all children of the specified root.")]
		[FormerlySerializedAs("target")]
		private Transform rootTransform;

		[Tooltip("The settings that the rig should update with, create them using the Create->JigglePhysics->Settings menu option.")]
		public JiggleSettingsBase jiggleSettings;

		[SerializeField]
		[Tooltip("The list of transforms to ignore during the jiggle. Each bone listed will also ignore all the children of the specified bone.")]
		private List<Transform> ignoredTransforms;

		public List<Collider> colliders;

		[Tooltip("An air force that is applied to the entire rig, this is useful to plug in some wind volumes from external sources.")]
		public Vector3 wind;

		[Tooltip("Level of detail manager. This system will control how the jiggle rig saves performance cost.")]
		public JiggleRigLOD levelOfDetail;

		[Tooltip("Draws some simple lines to show what the simulation is doing. Generally this should be disabled.")]
		[SerializeField]
		private bool debugDraw;

		private JiggleSettingsData data;

		private bool initialized;

		[HideInInspector]
		protected List<JiggleBone> simulatedPoints;

		private double accumulation;

		private bool dirtyFromEnable = false;

		private bool wasLODActive = true;

		public static float maxCatchupTime => Time.fixedDeltaTime * 4f;

		private bool NeedsCollisions => colliders.Count != 0;

		public Transform GetRootTransform()
		{
			return rootTransform;
		}

		public void PrepareBone(Vector3 position, JiggleRigLOD jiggleRigLOD)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized)
			{
				throw new UnityException("JiggleRig was never initialized. Please call JiggleRig.Initialize() if you're going to manually timestep.");
			}
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PrepareBone();
			}
			data = jiggleSettings.GetData();
			data = (((Object)(object)jiggleRigLOD != (Object)null) ? jiggleRigLOD.AdjustJiggleSettingsData(position, data) : data);
		}

		public void MatchAnimationInstantly()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.MatchAnimationInstantly();
			}
		}

		public void UpdateJiggle(Vector3 wind, double time)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.VerletPass(data, wind, time);
			}
			if (NeedsCollisions)
			{
				for (int num = simulatedPoints.Count - 1; num >= 0; num--)
				{
					simulatedPoints[num].CollisionPreparePass(data);
				}
			}
			foreach (JiggleBone simulatedPoint2 in simulatedPoints)
			{
				simulatedPoint2.ConstraintPass(data);
			}
			if (NeedsCollisions)
			{
				foreach (JiggleBone simulatedPoint3 in simulatedPoints)
				{
					simulatedPoint3.CollisionPass(jiggleSettings, colliders);
				}
			}
			foreach (JiggleBone simulatedPoint4 in simulatedPoints)
			{
				simulatedPoint4.SignalWritePosition(time);
			}
		}

		public void DeriveFinalSolve()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = simulatedPoints[0].DeriveFinalSolvePosition(Vector3.zero);
			Vector3 offset = simulatedPoints[0].transform.position - val;
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.DeriveFinalSolvePosition(offset);
			}
		}

		public void Pose(bool debugDraw)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			DeriveFinalSolve();
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PoseBone(data.blend);
				if (debugDraw)
				{
					simulatedPoint.DebugDraw(Color.red, Color.blue, interpolated: true);
				}
			}
		}

		public void PrepareTeleport()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PrepareTeleport();
			}
		}

		public void FinishTeleport()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.FinishTeleport();
			}
		}

		protected virtual void CreateSimulatedPoints(ICollection<JiggleBone> outputPoints, ICollection<Transform> ignoredTransforms, Transform currentTransform, JiggleBone parentJiggleBone)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			JiggleBone jiggleBone = new JiggleBone(currentTransform, parentJiggleBone);
			outputPoints.Add(jiggleBone);
			if (currentTransform.childCount == 0)
			{
				if (jiggleBone.parent == null)
				{
					if ((Object)(object)jiggleBone.transform.parent == (Object)null)
					{
						throw new UnityException("Can't have a singular jiggle bone with no parents. That doesn't even make sense!");
					}
					outputPoints.Add(new JiggleBone(null, jiggleBone));
				}
				else
				{
					outputPoints.Add(new JiggleBone(null, jiggleBone));
				}
				return;
			}
			for (int i = 0; i < currentTransform.childCount; i++)
			{
				if (!ignoredTransforms.Contains(currentTransform.GetChild(i)))
				{
					CreateSimulatedPoints(outputPoints, ignoredTransforms, currentTransform.GetChild(i), jiggleBone);
				}
			}
		}

		private void Awake()
		{
			Initialize();
		}

		private void OnEnable()
		{
			JiggleRigHandler.AddBuilder(this);
			dirtyFromEnable = true;
		}

		private void OnDisable()
		{
			JiggleRigHandler.RemoveBuilder(this);
			PrepareTeleport();
		}

		public void Initialize()
		{
			accumulation = 0.0;
			simulatedPoints = new List<JiggleBone>();
			if ((Object)(object)rootTransform == (Object)null)
			{
				return;
			}
			CreateSimulatedPoints(simulatedPoints, ignoredTransforms, rootTransform, null);
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.CalculateNormalizedIndex();
			}
			initialized = true;
		}

		public virtual void Advance(float deltaTime)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)levelOfDetail != (Object)null && !levelOfDetail.CheckActive(((Component)this).transform.position))
			{
				if (wasLODActive)
				{
					PrepareTeleport();
				}
				wasLODActive = false;
				return;
			}
			if (!wasLODActive)
			{
				FinishTeleport();
			}
			PrepareBone(((Component)this).transform.position, levelOfDetail);
			if (dirtyFromEnable)
			{
				FinishTeleport();
				dirtyFromEnable = false;
			}
			accumulation = Math.Min(accumulation + (double)deltaTime, maxCatchupTime);
			while (accumulation > (double)Time.fixedDeltaTime)
			{
				accumulation -= Time.fixedDeltaTime;
				double time = Time.timeAsDouble - accumulation;
				UpdateJiggle(wind, time);
			}
			Pose(debugDraw);
			wasLODActive = true;
		}

		private void OnDrawGizmos()
		{
			if (!initialized || simulatedPoints == null)
			{
				Initialize();
			}
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.OnDrawGizmos(jiggleSettings);
			}
		}

		private void OnValidate()
		{
			if ((Object)(object)rootTransform == (Object)null)
			{
				rootTransform = ((Component)this).transform;
			}
			if (!Application.isPlaying)
			{
				Initialize();
			}
		}
	}
	public static class JiggleRigHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UpdateFunction <0>__UpdateJiggleRigs;
		}

		private static bool initialized = false;

		private static HashSet<JiggleRigBuilder> builders = new HashSet<JiggleRigBuilder>();

		private static void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			if (!initialized)
			{
				PlayerLoopSystem currentPlayerLoop = PlayerLoop.GetCurrentPlayerLoop();
				PlayerLoopSystem self = currentPlayerLoop;
				PlayerLoopSystem systemToInject = default(PlayerLoopSystem);
				object obj = <>O.<0>__UpdateJiggleRigs;
				if (obj == null)
				{
					UpdateFunction val = UpdateJiggleRigs;
					<>O.<0>__UpdateJiggleRigs = val;
					obj = (object)val;
				}
				systemToInject.updateDelegate = (UpdateFunction)obj;
				systemToInject.type = typeof(JiggleRigHandler);
				currentPlayerLoop = self.InjectAt<PostLateUpdate>(systemToInject);
				PlayerLoop.SetPlayerLoop(currentPlayerLoop);
				initialized = true;
			}
		}

		private static void UpdateJiggleRigs()
		{
			CachedSphereCollider.StartPass();
			foreach (JiggleRigBuilder builder in builders)
			{
				builder.Advance(Time.deltaTime);
			}
			CachedSphereCollider.FinishedPass();
		}

		public static void AddBuilder(JiggleRigBuilder builder)
		{
			builders.Add(builder);
			Initialize();
		}

		public static void RemoveBuilder(JiggleRigBuilder builder)
		{
			builders.Remove(builder);
		}

		private static PlayerLoopSystem InjectAt<T>(this PlayerLoopSystem self, PlayerLoopSystem systemToInject)
		{
			//IL_0001: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			int num = FindIndexOfSubsystem<T>(self.subSystemList);
			if (num == -1)
			{
				throw new UnityException($"Failed to find PlayerLoopSystem with type{typeof(T)}");
			}
			List<PlayerLoopSystem> list = new List<PlayerLoopSystem>(self.subSystemList[num].subSystemList);
			foreach (PlayerLoopSystem item2 in list)
			{
				if (item2.type != typeof(JiggleRigBuilder))
				{
					continue;
				}
				Debug.LogWarning((object)$"Tried to inject a PlayerLoopSystem ({systemToInject.type}) more than once! Ignoring the second injection.");
				return self;
			}
			PlayerLoopSystem item = default(PlayerLoopSystem);
			object obj = <>O.<0>__UpdateJiggleRigs;
			if (obj == null)
			{
				UpdateFunction val = UpdateJiggleRigs;
				<>O.<0>__UpdateJiggleRigs = val;
				obj = (object)val;
			}
			item.updateDelegate = (UpdateFunction)obj;
			item.type = typeof(JiggleRigHandler);
			list.Insert(0, item);
			self.subSystemList[num].subSystemList = list.ToArray();
			return self;
		}

		private static int FindIndexOfSubsystem<T>(PlayerLoopSystem[] list, int index = -1)
		{
			if (list == null)
			{
				return -1;
			}
			for (int i = 0; i < list.Length; i++)
			{
				if (list[i].type == typeof(T))
				{
					return i;
				}
			}
			return -1;
		}
	}
	public abstract class JiggleRigLOD : ScriptableObject
	{
		public abstract bool CheckActive(Vector3 position);

		public abstract JiggleSettingsData AdjustJiggleSettingsData(Vector3 position, JiggleSettingsData data);
	}
	[CreateAssetMenu(fileName = "JiggleRigSimpleLOD", menuName = "JigglePhysics/JiggleRigSimpleLOD", order = 1)]
	public class JiggleRigSimpleLOD : JiggleRigLOD
	{
		[Tooltip("Distance to disable the jiggle rig")]
		[SerializeField]
		private float distance;

		[Tooltip("Level of detail manager. This system will control how the jiggle rig saves performance cost.")]
		[SerializeField]
		private float blend;

		[NonSerialized]
		private Camera currentCamera;

		[NonSerialized]
		private Transform cameraTransform;

		private bool TryGetCamera(out Camera camera)
		{
			if ((Object)(object)currentCamera == (Object)null || !((Component)currentCamera).CompareTag("MainCamera"))
			{
				currentCamera = Camera.main;
			}
			camera = currentCamera;
			return (Object)(object)currentCamera != (Object)null;
		}

		public override bool CheckActive(Vector3 position)
		{
			//IL_001b: 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 (!TryGetCamera(out var camera))
			{
				return false;
			}
			return Vector3.Distance(((Component)camera).transform.position, position) < distance;
		}

		public override JiggleSettingsData AdjustJiggleSettingsData(Vector3 position, JiggleSettingsData data)
		{
			//IL_001b: 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 (!TryGetCamera(out var camera))
			{
				return data;
			}
			float num = (Vector3.Distance(((Component)camera).transform.position, position) - distance + blend) / blend;
			num = Mathf.Clamp01(1f - num);
			data.blend = num;
			return data;
		}
	}
	public struct JiggleSettingsData
	{
		public float gravityMultiplier;

		public float friction;

		public float angleElasticity;

		public float blend;

		public float airDrag;

		public float lengthElasticity;

		public float elasticitySoften;

		public float radiusMultiplier;

		public static JiggleSettingsData Lerp(JiggleSettingsData a, JiggleSettingsData b, float t)
		{
			JiggleSettingsData result = default(JiggleSettingsData);
			result.gravityMultiplier = Mathf.Lerp(a.gravityMultiplier, b.gravityMultiplier, t);
			result.friction = Mathf.Lerp(a.friction, b.friction, t);
			result.angleElasticity = Mathf.Lerp(a.angleElasticity, b.angleElasticity, t);
			result.blend = Mathf.Lerp(a.blend, b.blend, t);
			result.airDrag = Mathf.Lerp(a.airDrag, b.airDrag, t);
			result.lengthElasticity = Mathf.Lerp(a.lengthElasticity, b.lengthElasticity, t);
			result.elasticitySoften = Mathf.Lerp(a.elasticitySoften, b.elasticitySoften, t);
			result.radiusMultiplier = Mathf.Lerp(a.radiusMultiplier, b.radiusMultiplier, t);
			return result;
		}
	}
	[CreateAssetMenu(fileName = "JiggleSettings", menuName = "JigglePhysics/Settings", order = 1)]
	public class JiggleSettings : JiggleSettingsBase
	{
		[SerializeField]
		[Range(0f, 2f)]
		[Tooltip("How much gravity to apply to the simulation, it is a multiplier of the Physics.gravity setting.")]
		private float gravityMultiplier = 1f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much mechanical friction to apply, this is specifically how quickly oscillations come to rest.")]
		private float friction = 0.4f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much angular force is applied to bring it to the target shape.")]
		private float angleElasticity = 0.4f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much of the simulation should be expressed. A value of 0 would make the jiggle have zero effect. A value of 1 gives the full movement as intended. 0.5 would ")]
		private float blend = 1f;

		[FormerlySerializedAs("airFriction")]
		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much jiggled objects should get dragged behind by moving through the air. Or how \"thick\" the air is.")]
		private float airDrag = 0.1f;

		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How rigidly the rig holds its length. Low values cause lots of squash and stretch!")]
		private float lengthElasticity = 0.8f;

		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much to allow free bone motion before engaging elasticity.")]
		private float elasticitySoften = 0f;

		[HideInInspector]
		[SerializeField]
		[Tooltip("How much radius points have, only used for collisions. Set to 0 to disable collisions")]
		private float radiusMultiplier = 0f;

		[HideInInspector]
		[SerializeField]
		[Tooltip("How the radius is expressed as a curve along the bone chain from root to child.")]
		private AnimationCurve radiusCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 1f),
			new Keyframe(1f, 0f)
		});

		public override JiggleSettingsData GetData()
		{
			JiggleSettingsData result = default(JiggleSettingsData);
			result.gravityMultiplier = gravityMultiplier;
			result.friction = friction;
			result.airDrag = airDrag;
			result.blend = blend;
			result.angleElasticity = angleElasticity;
			result.elasticitySoften = elasticitySoften;
			result.lengthElasticity = lengthElasticity;
			result.radiusMultiplier = radiusMultiplier;
			return result;
		}

		public void SetData(JiggleSettingsData data)
		{
			gravityMultiplier = data.gravityMultiplier;
			friction = data.friction;
			angleElasticity = data.angleElasticity;
			blend = data.blend;
			airDrag = data.airDrag;
			lengthElasticity = data.lengthElasticity;
			elasticitySoften = data.elasticitySoften;
			radiusMultiplier = data.radiusMultiplier;
		}

		public override float GetRadius(float normalizedIndex)
		{
			return radiusMultiplier * radiusCurve.Evaluate(normalizedIndex);
		}

		public void SetRadiusCurve(AnimationCurve curve)
		{
			radiusCurve = curve;
		}
	}
	public class JiggleSettingsBase : ScriptableObject
	{
		public virtual JiggleSettingsData GetData()
		{
			return default(JiggleSettingsData);
		}

		public virtual float GetRadius(float normalizedIndex)
		{
			return 0f;
		}
	}
	[CreateAssetMenu(fileName = "JiggleSettingsBlend", menuName = "JigglePhysics/Blend Settings", order = 1)]
	public class JiggleSettingsBlend : JiggleSettingsBase
	{
		[Tooltip("The list of jiggle settings to blend between.")]
		public List<JiggleSettings> blendSettings;

		[Range(0f, 1f)]
		[Tooltip("A value from 0 to 1 that linearly blends between all of the blendSettings.")]
		public float normalizedBlend;

		public override JiggleSettingsData GetData()
		{
			int num = blendSettings.Count - 1;
			float num2 = Mathf.Clamp01(normalizedBlend);
			int num3 = Mathf.Clamp(Mathf.FloorToInt(num2 * (float)num), 0, num);
			int index = Mathf.Clamp(Mathf.FloorToInt(num2 * (float)num) + 1, 0, num);
			return JiggleSettingsData.Lerp(blendSettings[num3].GetData(), blendSettings[index].GetData(), Mathf.Clamp01(num2 * (float)num - (float)num3));
		}

		public override float GetRadius(float normalizedIndex)
		{
			float num = Mathf.Clamp01(normalizedBlend);
			int num2 = Mathf.FloorToInt(num * (float)blendSettings.Count);
			int num3 = Mathf.FloorToInt(num * (float)blendSettings.Count) + 1;
			return Mathf.Lerp(blendSettings[Mathf.Clamp(num2, 0, blendSettings.Count - 1)].GetRadius(normalizedIndex), blendSettings[Mathf.Clamp(num3, 0, blendSettings.Count - 1)].GetRadius(normalizedIndex), Mathf.Clamp01(num * (float)blendSettings.Count - (float)num2));
		}
	}
	[BepInPlugin("1.Waga.JigglePhysicsPlugin", "JigglePhysicsPlugin", "1.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private static Plugin instance;

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			instance = this;
			_harmony = new Harmony("JigglePhysicsPlugin");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"JigglePhysicsPlugin loaded!");
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}
	}
	public class PositionSignal
	{
		private struct Frame
		{
			public Vector3 position;

			public double time;
		}

		private Frame previousFrame;

		private Frame currentFrame;

		public PositionSignal(Vector3 startPosition, double time)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			currentFrame = (previousFrame = new Frame
			{
				position = startPosition,
				time = time
			});
		}

		public void SetPosition(Vector3 position, double time)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			previousFrame = currentFrame;
			currentFrame = new Frame
			{
				position = position,
				time = time
			};
		}

		public void OffsetSignal(Vector3 offset)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			previousFrame = new Frame
			{
				position = previousFrame.position + offset,
				time = previousFrame.time
			};
			currentFrame = new Frame
			{
				position = currentFrame.position + offset,
				time = previousFrame.time
			};
		}

		public void FlattenSignal(double time, Vector3 position)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			previousFrame = new Frame
			{
				position = position,
				time = time - (double)(JiggleRigBuilder.maxCatchupTime * 2f)
			};
			currentFrame = new Frame
			{
				position = position,
				time = time - (double)JiggleRigBuilder.maxCatchupTime
			};
		}

		public Vector3 GetCurrent()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return currentFrame.position;
		}

		public Vector3 GetPrevious()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return previousFrame.position;
		}

		public Vector3 SamplePosition(double time)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			double num = currentFrame.time - previousFrame.time;
			if (num == 0.0)
			{
				return previousFrame.position;
			}
			double num2 = (time - previousFrame.time) / num;
			return Vector3.Lerp(previousFrame.position, currentFrame.position, (float)num2);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "JigglePhysicsPlugin";

		public const string PLUGIN_NAME = "JigglePhysicsPlugin";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

mods/Jordo-NeedyCats-1.1.1/BepInEx/plugins/NeedyCats.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using Unity.Netcode.Samples;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NeedyCats")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NeedyCats")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c7d3e258-85ed-4246-9766-b0915f7aec88")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace NeedyCats
{
	public class NeedyCatProp : PhysicsProp, INoiseListener
	{
		[Space(3f)]
		public Animator animator;

		public AudioSource audioSource;

		public SkinnedMeshRenderer skinnedMeshRenderer;

		[Space(3f)]
		public Vector2 IntervalMeow;

		public Vector2 IntervalMove;

		public Vector2 IntervalSitAnimChange;

		public Vector2 IntervalIdleAnimChange;

		public float WalkingSpeed = 1f;

		public float RunningSpeed = 8f;

		private (int, float)[] placeableMeowInterval;

		[HideInInspector]
		public (string, int)[] CatNames;

		private float timeBeforeNextMove = 1f;

		private float timeBeforeNextMeow = 1f;

		private float timeBeforeNextSitAnim = 1f;

		private int sitAnimationsLength = 3;

		private float timeBeforeNextIdleAnim = 1f;

		private int idleAnimationsLength = 4;

		private bool isSitting;

		private int materialIndex;

		private int nameIndex;

		private bool hasLoadedSave;

		private HoarderBugItem hoarderBugItem;

		[Space(3f)]
		public AudioClip[] noiseSFX;

		public AudioClip[] fleeSFX;

		public AudioClip[] calmSFX;

		[Space(3f)]
		public float noiseRange = 65f;

		public float maxLoudness = 1f;

		public float minLoudness = 0.95f;

		public float minPitch = 0.9f;

		public float maxPitch = 1f;

		private NavMeshAgent agent;

		private Random random;

		[Space(3f)]
		public Vector3 destination;

		private GameObject[] allAINodes;

		private NavMeshPath navmeshPath;

		private float velX;

		private float velY;

		private Vector3 previousPosition;

		private Vector3 agentLocalVelocity;

		private ClientNetworkTransform clientNetworkTransform;

		private bool isBeingHoarded
		{
			get
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if (hoarderBugItem != null)
				{
					return Vector3.Distance(((Component)this).transform.position, hoarderBugItem.itemNestPosition) < 2f;
				}
				return false;
			}
		}

		public void Awake()
		{
		}

		public override void Start()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			((GrabbableObject)this).Start();
			try
			{
				if ((Object)(object)agent == (Object)null)
				{
					agent = ((Component)this).GetComponent<NavMeshAgent>();
				}
				if ((Object)(object)animator == (Object)null)
				{
					animator = ((Component)this).GetComponentInChildren<Animator>();
				}
				if ((Object)(object)skinnedMeshRenderer == (Object)null)
				{
					skinnedMeshRenderer = ((Component)this).GetComponentInChildren<SkinnedMeshRenderer>();
				}
				clientNetworkTransform = ((Component)this).GetComponent<ClientNetworkTransform>();
				random = new Random(StartOfRound.Instance.randomMapSeed + 85);
				GameObject[] first = GameObject.FindGameObjectsWithTag("AINode");
				GameObject[] second = GameObject.FindGameObjectsWithTag("OutsideAINode");
				allAINodes = first.Concat(second).ToArray();
				agent.updatePosition = false;
				destination = ((Component)this).transform.position;
				navmeshPath = new NavMeshPath();
				((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback += NetworkManager_OnClientConnectedCallback;
				placeableMeowInterval = new(int, float)[3]
				{
					(22, 10f),
					(21, 2f),
					(4, 6f)
				};
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"Error when initializing variables for {((Object)((Component)this).gameObject).name} : {arg}");
			}
			if (((NetworkBehaviour)this).IsServer && !hasLoadedSave)
			{
				nameIndex = Random.Range(0, CatNames.Length);
				SetCatNameServerRpc(CatNames[nameIndex].Item1);
				if (CatNames[nameIndex].Item2 != -1)
				{
					materialIndex = CatNames[nameIndex].Item2;
				}
				else
				{
					materialIndex = Random.Range(0, ((GrabbableObject)this).itemProperties.materialVariants.Length);
				}
				SetCatMaterialServerRpc(materialIndex);
			}
		}

		public override void OnDestroy()
		{
			((NetworkBehaviour)this).OnDestroy();
			((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback -= NetworkManager_OnClientConnectedCallback;
		}

		private void NetworkManager_OnClientConnectedCallback(ulong obj)
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				SetCatMaterialServerRpc(materialIndex);
				SetCatNameServerRpc(CatNames[nameIndex].Item1);
				if (isSitting)
				{
					MakeCatSitServerRpc(sit: true);
				}
			}
		}

		public override void LoadItemSaveData(int saveData)
		{
			((MonoBehaviour)this).StartCoroutine(NetworkSafeLoadItemSaveData(saveData));
		}

		private IEnumerator NetworkSafeLoadItemSaveData(int saveData)
		{
			yield return ((NetworkBehaviour)this).IsSpawned;
			if (((NetworkBehaviour)this).IsServer)
			{
				<>n__0(saveData);
				int catMaterialServerRpc = (saveData >> 16) & 0xFFFF;
				int num = saveData & 0xFFFF;
				if (num > CatNames.Length)
				{
					num = Random.Range(0, CatNames.Length);
				}
				SetCatNameServerRpc(CatNames[num].Item1);
				if (CatNames[num].Item2 != -1)
				{
					catMaterialServerRpc = CatNames[num].Item2;
				}
				SetCatMaterialServerRpc(catMaterialServerRpc);
				materialIndex = catMaterialServerRpc;
				nameIndex = num;
				hasLoadedSave = true;
			}
		}

		public override int GetItemDataToSave()
		{
			return (materialIndex << 16) | nameIndex;
		}

		private void SynchronizeAnimator(float maxSpeed = 4f)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			agentLocalVelocity = ((Component)animator).transform.InverseTransformDirection(Vector3.ClampMagnitude(((Component)this).transform.position - previousPosition, 1f) / (Time.deltaTime * 2f));
			animator.SetBool("move", ((Vector3)(ref agentLocalVelocity)).magnitude > 0.05f);
			velX = Mathf.Lerp(velX, agentLocalVelocity.x, 10f * Time.deltaTime);
			animator.SetFloat("velx", Mathf.Clamp(velX, 0f - maxSpeed, maxSpeed));
			velY = Mathf.Lerp(velY, agentLocalVelocity.z, 10f * Time.deltaTime);
			animator.SetFloat("vely", Mathf.Clamp(velY, 0f - maxSpeed, maxSpeed));
			previousPosition = ((Component)this).transform.position;
		}

		public override void GrabItem()
		{
			animator.SetBool("move", false);
			animator.SetFloat("velx", 0f);
			animator.SetFloat("vely", 0f);
			animator.SetBool("held", true);
			isSitting = false;
			((GrabbableObject)this).GrabItem();
			if (((NetworkBehaviour)this).IsOwner)
			{
				HUDManager.Instance.DisplayTip("Cat Facts", "Too noisy? Give your cat a pet to quiet it down for a bit!", false, true, "LC_NeedyCatsTip");
			}
		}

		public override void DiscardItem()
		{
			animator.SetBool("held", false);
			((GrabbableObject)this).DiscardItem();
		}

		public override void GrabItemFromEnemy(EnemyAI enemy)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			((GrabbableObject)this).isHeldByEnemy = true;
			animator.SetBool("move", false);
			animator.SetFloat("velx", 0f);
			animator.SetFloat("vely", 0f);
			animator.SetBool("held", true);
			((GrabbableObject)this).GrabItemFromEnemy(enemy);
			if (((NetworkBehaviour)this).IsServer && enemy is HoarderBugAI)
			{
				HoarderBugAI val = (HoarderBugAI)enemy;
				hoarderBugItem = (((Object)(object)val.heldItem.itemGrabbableObject == (Object)(object)this) ? val.heldItem : null);
			}
		}

		public override void DiscardItemFromEnemy()
		{
			((GrabbableObject)this).isHeldByEnemy = false;
			animator.SetBool("held", false);
			((GrabbableObject)this).DiscardItemFromEnemy();
		}

		public override void Update()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)clientNetworkTransform).enabled = !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy;
			if (((NetworkBehaviour)this).IsServer && !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy && !((NetworkBehaviour)this).IsOwner)
			{
				((Component)this).GetComponent<NetworkObject>().RemoveOwnership();
			}
			if (!((GrabbableObject)this).isInElevator && StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				((Behaviour)agent).enabled = !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy && ((GrabbableObject)this).reachedFloorTarget && !(((GrabbableObject)this).fallTime < 1f);
				if (((GrabbableObject)this).fallTime >= 1f && !((GrabbableObject)this).reachedFloorTarget)
				{
					((GrabbableObject)this).targetFloorPosition = ((Component)this).transform.position;
					destination = ((Component)this).transform.position;
					previousPosition = ((Component)this).transform.position;
					((Behaviour)agent).enabled = true;
				}
			}
			if (((GrabbableObject)this).fallTime >= 1f && !((GrabbableObject)this).reachedFloorTarget && animator.GetBool("held"))
			{
				animator.SetBool("held", false);
			}
			if (((GrabbableObject)this).isHeld || ((GrabbableObject)this).isHeldByEnemy || !((GrabbableObject)this).reachedFloorTarget || ((GrabbableObject)this).fallTime < 1f || ((GrabbableObject)this).isInElevator)
			{
				((GrabbableObject)this).Update();
			}
			if (((NetworkBehaviour)this).IsServer && !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy && (((GrabbableObject)this).isInElevator || isBeingHoarded) && !isSitting)
			{
				MakeCatSitServerRpc(sit: true);
			}
			else if (((NetworkBehaviour)this).IsServer && !((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy && !((GrabbableObject)this).isInElevator && !isBeingHoarded && isSitting && StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				MakeCatSitServerRpc(sit: false);
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				if (isSitting)
				{
					if (timeBeforeNextSitAnim <= 0f)
					{
						SetCatSitAnimationServerRpc(Random.Range(0, sitAnimationsLength));
						timeBeforeNextSitAnim = Random.Range(IntervalSitAnimChange.x, IntervalSitAnimChange.y);
					}
					timeBeforeNextSitAnim -= Time.deltaTime;
				}
				else
				{
					if (timeBeforeNextIdleAnim <= 0f)
					{
						SetCatIdleAnimationServerRpc(Random.Range(0, idleAnimationsLength));
						timeBeforeNextIdleAnim = Random.Range(IntervalIdleAnimChange.x, IntervalIdleAnimChange.y);
					}
					timeBeforeNextIdleAnim -= Time.deltaTime;
				}
				if (timeBeforeNextMeow <= 0f)
				{
					MakeCatMeowServerRpc();
					float num = 0f;
					if (((GrabbableObject)this).isInElevator)
					{
						PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
						foreach (PlayerControllerB val in allPlayerScripts)
						{
							if (val.isInElevator)
							{
								num += 2f;
								break;
							}
						}
						(int, float)[] array = placeableMeowInterval;
						for (int j = 0; j < array.Length; j++)
						{
							(int, float) tuple = array[j];
							if (StartOfRound.Instance.SpawnedShipUnlockables.ContainsKey(tuple.Item1))
							{
								num += tuple.Item2;
							}
						}
					}
					timeBeforeNextMeow = Random.Range(IntervalMeow.x + num, IntervalMeow.y + num);
				}
				timeBeforeNextMeow -= Time.deltaTime;
				if (!((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy && !((GrabbableObject)this).isInElevator && !isBeingHoarded && StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
				{
					if (timeBeforeNextMove <= 0f)
					{
						SetRandomDestination();
						timeBeforeNextMove = Random.Range(IntervalMove.x, IntervalMove.y);
					}
					timeBeforeNextMove -= Time.deltaTime;
					((Component)this).transform.position = agent.nextPosition;
				}
			}
			if (!((GrabbableObject)this).isHeld && !((GrabbableObject)this).isHeldByEnemy)
			{
				SynchronizeAnimator();
			}
		}

		public void SetDestinationToPosition(Vector3 position, bool checkForPath = false)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_002e: Expected O, but got Unknown
			//IL_0034: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (checkForPath)
			{
				position = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 1.75f, -1);
				navmeshPath = new NavMeshPath();
				if (!agent.CalculatePath(position, navmeshPath))
				{
					Debug.Log((object)(((Object)((Component)this).gameObject).name + " calculatepath returned false."));
					return;
				}
				if (Vector3.Distance(navmeshPath.corners[navmeshPath.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 2.7f, -1)) > 1.55f)
				{
					Debug.Log((object)(((Object)((Component)this).gameObject).name + " path calculation went wrong."));
					return;
				}
			}
			destination = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, -1f, -1);
			agent.SetDestination(destination);
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (((NetworkBehaviour)this).IsOwner)
			{
				MakeCatCalmServerRpc();
			}
		}

		public void SetRandomDestination()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position + Random.insideUnitSphere * 5f;
			agent.speed = WalkingSpeed;
			SetDestinationToPosition(position);
		}

		private void PlayCatNoise(AudioClip[] array, bool audible = true)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			int num = random.Next(0, array.Length);
			float num2 = (float)random.Next((int)(minLoudness * 100f), (int)(maxLoudness * 100f)) / 100f;
			float pitch = (float)random.Next((int)(minPitch * 100f), (int)(maxPitch * 100f)) / 100f;
			audioSource.pitch = pitch;
			audioSource.PlayOneShot(array[num], num2);
			WalkieTalkie.TransmitOneShotAudio(audioSource, array[num], num2 - 0.4f);
			if (audible)
			{
				noiseRange = (((GrabbableObject)this).isInElevator ? (noiseRange - 2.5f) : noiseRange);
				RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, noiseRange, num2, 0, ((GrabbableObject)this).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 8881);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MakeCatMeowServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3454429685u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3454429685u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					MakeCatMeowClientRpc();
				}
			}
		}

		[ClientRpc]
		public void MakeCatMeowClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1946573138u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1946573138u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlayCatNoise(noiseSFX);
					animator.SetTrigger("meow");
				}
			}
		}

		[ServerRpc]
		public void MakeCatCalmServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2784153610u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2784153610u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			float num = 0f;
			if (((GrabbableObject)this).isInElevator)
			{
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val3 in allPlayerScripts)
				{
					if (val3.isInElevator)
					{
						num += 2f;
						break;
					}
				}
				(int, float)[] array = placeableMeowInterval;
				for (int j = 0; j < array.Length; j++)
				{
					(int, float) tuple = array[j];
					if (StartOfRound.Instance.SpawnedShipUnlockables.ContainsKey(tuple.Item1))
					{
						num += tuple.Item2;
					}
				}
			}
			timeBeforeNextMeow = Random.Range(IntervalMeow.x + num + 3f, IntervalMeow.y + num + 6f);
			MakeCatCalmClientRpc();
		}

		[ClientRpc]
		public void MakeCatCalmClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2302897036u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2302897036u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((GrabbableObject)this).playerHeldBy.doingUpperBodyEmote = 1.16f;
					((GrabbableObject)this).playerHeldBy.playerBodyAnimator.SetTrigger("PullGrenadePin2");
					((MonoBehaviour)this).StartCoroutine(PlayCatCalmNoiseDelayed());
				}
			}
		}

		private IEnumerator PlayCatCalmNoiseDelayed()
		{
			yield return (object)new WaitForSeconds(0.5f);
			PlayCatNoise(calmSFX, audible: false);
		}

		[ServerRpc]
		public void MakeCatSitServerRpc(bool sit)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2411027775u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref sit, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2411027775u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				MakeCatSitClientRpc(sit);
			}
		}

		[ClientRpc]
		public void MakeCatSitClientRpc(bool sit)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3921800473u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref sit, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3921800473u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					animator.SetBool("sit", sit);
					isSitting = sit;
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetCatMaterialServerRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2046492207u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2046492207u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					SetCatMaterialClientRpc(index);
				}
			}
		}

		[ClientRpc]
		public void SetCatMaterialClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3875721248u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3875721248u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && (Object)(object)skinnedMeshRenderer != (Object)null)
				{
					((Renderer)skinnedMeshRenderer).sharedMaterial = ((GrabbableObject)this).itemProperties.materialVariants[index];
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetCatNameServerRpc(string name)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3049925245u, val, (RpcDelivery)0);
				bool flag = name != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(name, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3049925245u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				SetCatNameClientRpc(name);
			}
		}

		[ClientRpc]
		public void SetCatNameClientRpc(string name)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1321450034u, val, (RpcDelivery)0);
				bool flag = name != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(name, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1321450034u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				((Component)this).GetComponentInChildren<ScanNodeProperties>().headerText = "Cat (" + name + ")";
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetCatIdleAnimationServerRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1770904636u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1770904636u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					SetCatIdleAnimationClientRpc(index);
				}
			}
		}

		[ClientRpc]
		public void SetCatIdleAnimationClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(283245169u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 283245169u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					animator.SetInteger("idleAnimation", index);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetCatSitAnimationServerRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1062797608u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1062797608u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					SetCatSitAnimationClientRpc(index);
				}
			}
		}

		[ClientRpc]
		public void SetCatSitAnimationClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4162097660u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4162097660u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					animator.SetInteger("sitAnimation", index);
				}
			}
		}

		public virtual void DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot, int noiseID)
		{
			//IL_0039: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (((GrabbableObject)this).isHeld || ((GrabbableObject)this).isHeldByEnemy || noiseID == 8881 || noiseID == 75 || ((GrabbableObject)this).isInShipRoom || !StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				return;
			}
			Vector3 val = noisePosition - ((Component)this).transform.position;
			if (!(((Vector3)(ref val)).magnitude < 5f) || !(noiseLoudness > 0.8f))
			{
				return;
			}
			PlayCatNoise(fleeSFX);
			if (((NetworkBehaviour)this).IsServer)
			{
				Vector3 position = ((Component)this).transform.position - ((Vector3)(ref val)).normalized * 20f;
				GameObject[] array = allAINodes.OrderBy((GameObject x) => Vector3.Distance(position, x.transform.position)).ToArray();
				SetDestinationToPosition(array[0].transform.position);
				agent.speed = RunningSpeed;
				timeBeforeNextMove = Random.Range(IntervalMove.x + 1f, IntervalMove.y + 2f);
			}
		}

		[CompilerGenerated]
		[DebuggerHidden]
		private void <>n__0(int saveData)
		{
			((GrabbableObject)this).LoadItemSaveData(saveData);
		}

		protected override void __initializeVariables()
		{
			((PhysicsProp)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_NeedyCatProp()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3454429685u, new RpcReceiveHandler(__rpc_handler_3454429685));
			NetworkManager.__rpc_func_table.Add(1946573138u, new RpcReceiveHandler(__rpc_handler_1946573138));
			NetworkManager.__rpc_func_table.Add(2784153610u, new RpcReceiveHandler(__rpc_handler_2784153610));
			NetworkManager.__rpc_func_table.Add(2302897036u, new RpcReceiveHandler(__rpc_handler_2302897036));
			NetworkManager.__rpc_func_table.Add(2411027775u, new RpcReceiveHandler(__rpc_handler_2411027775));
			NetworkManager.__rpc_func_table.Add(3921800473u, new RpcReceiveHandler(__rpc_handler_3921800473));
			NetworkManager.__rpc_func_table.Add(2046492207u, new RpcReceiveHandler(__rpc_handler_2046492207));
			NetworkManager.__rpc_func_table.Add(3875721248u, new RpcReceiveHandler(__rpc_handler_3875721248));
			NetworkManager.__rpc_func_table.Add(3049925245u, new RpcReceiveHandler(__rpc_handler_3049925245));
			NetworkManager.__rpc_func_table.Add(1321450034u, new RpcReceiveHandler(__rpc_handler_1321450034));
			NetworkManager.__rpc_func_table.Add(1770904636u, new RpcReceiveHandler(__rpc_handler_1770904636));
			NetworkManager.__rpc_func_table.Add(283245169u, new RpcReceiveHandler(__rpc_handler_283245169));
			NetworkManager.__rpc_func_table.Add(1062797608u, new RpcReceiveHandler(__rpc_handler_1062797608));
			NetworkManager.__rpc_func_table.Add(4162097660u, new RpcReceiveHandler(__rpc_handler_4162097660));
		}

		private static void __rpc_handler_3454429685(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).MakeCatMeowServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1946573138(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).MakeCatMeowClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2784153610(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).MakeCatCalmServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2302897036(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).MakeCatCalmClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2411027775(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00ab: 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_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				bool sit = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref sit, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).MakeCatSitServerRpc(sit);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3921800473(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool sit = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref sit, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).MakeCatSitClientRpc(sit);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2046492207(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catMaterialServerRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catMaterialServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).SetCatMaterialServerRpc(catMaterialServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3875721248(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catMaterialClientRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catMaterialClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).SetCatMaterialClientRpc(catMaterialClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3049925245(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string catNameServerRpc = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref catNameServerRpc, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).SetCatNameServerRpc(catNameServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1321450034(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string catNameClientRpc = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref catNameClientRpc, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).SetCatNameClientRpc(catNameClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1770904636(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catIdleAnimationServerRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catIdleAnimationServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).SetCatIdleAnimationServerRpc(catIdleAnimationServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_283245169(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catIdleAnimationClientRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catIdleAnimationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).SetCatIdleAnimationClientRpc(catIdleAnimationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1062797608(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catSitAnimationServerRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catSitAnimationServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NeedyCatProp)(object)target).SetCatSitAnimationServerRpc(catSitAnimationServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4162097660(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int catSitAnimationClientRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref catSitAnimationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NeedyCatProp)(object)target).SetCatSitAnimationClientRpc(catSitAnimationClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "NeedyCatProp";
		}
	}
	public class NoiseListenerRedirect : MonoBehaviour, INoiseListener
	{
		private INoiseListener target;

		public void Awake()
		{
			target = ((Component)((Component)this).transform.parent).GetComponent<INoiseListener>();
		}

		public void DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot, int noiseID)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			INoiseListener obj = target;
			if (obj != null)
			{
				obj.DetectNoise(noisePosition, noiseLoudness, timesPlayedInOneSpot, noiseID);
			}
		}
	}
	[BepInPlugin("Jordo.NeedyCats", "Needy Cats", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class NeedyCatsBase : BaseUnityPlugin
	{
		public static class Assets
		{
			public static string mainAssetBundleName = "needycats";

			public static AssetBundle MainAssetBundle = null;

			private static string GetAssemblyName()
			{
				return Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];
			}

			public static void PopulateAssets()
			{
				if ((Object)(object)MainAssetBundle == (Object)null)
				{
					using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName))
					{
						MainAssetBundle = AssetBundle.LoadFromStream(stream);
					}
				}
			}
		}

		private const string modGUID = "Jordo.NeedyCats";

		private const string modName = "Needy Cats";

		private const string modVersion = "1.1.1";

		private readonly Harmony harmony = new Harmony("Jordo.NeedyCats");

		public static NeedyCatsBase Instance;

		private static List<(string, int)> catNames = new List<(string, int)>();

		private static ConfigEntry<int> spawnRate;

		private static ConfigEntry<string> catNamesConfig;

		internal static ManualLogSource mls;

		private string defaultCatNames = "One:Stripes,Bella,Tigger,Chloe,Shadow,Luna,Oreo,Oliver,Kitty,Lucy,Molly,Jasper,Smokey,Gizmo,Simba,Tiger,Charlie,Angel,Jack,Lily,Peanut,Toby,Baby,Loki,Midnight,Milo,Princess,Sophie,Harley,Max,Missy,Rocky,Zoe,CoCo,Misty,Nala,Oscar,Pepper,Sasha,Buddy,Pumpkin,Kiki,Mittens,Bailey,Callie,Lucky,Patches,Simon,Garfield:Orange,George,Maggie,Sammy,Sebastian,Boots,Cali,Felix,Lilly,Phoebe,Sassy,Tucker,Bandit,Dexter,Fiona,Jake,Precious,Romeo,Snickers,Socks,Daisy,Gracie,Lola,Sadie,Sox,Casper,Fluffy,Marley,Minnie,Sweetie,Ziggy,Belle,Blackie,Chester,Frankie,Ginger,Muffin,Murphy,Rusty,Scooter,Batman,Boo,Cleo,Izzy,Jasmine,Mimi,Sugar,Cupcake,Dusty,Leo,Noodle,Panda,Peaches";

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("Jordo.NeedyCats");
			PatchNetcode();
			Assets.PopulateAssets();
			spawnRate = ((BaseUnityPlugin)this).Config.Bind<int>("NeedyCats", "Spawn rate", 20, "Sets the cat's spawn rate (This affects all moons).");
			catNamesConfig = ((BaseUnityPlugin)this).Config.Bind<string>("NeedyCats", "Cat names", defaultCatNames, "Possible cat names separated by a colon (,). If the cat's name is followed by ':', you can input a material that'll be forced for that name among the following: Black, White, Spots, Boots, Orange, Stripes. You can find an image showcasing each material on the mod's wiki on Thunderstore. This list must contain at least one name. Example string: 'Daisy,Garfield:Orange,Chloe'");
			string[] array = catNamesConfig.Value.Split(new char[1] { ',' });
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { ':' });
				catNames.Add((array2[0], (array2.Length > 1) ? GetMaterialID(array2[1]) : (-1)));
			}
			harmony.PatchAll(typeof(NeedyCatsBase));
			mls.LogInfo((object)"Initialized Needy Cats");
		}

		private int GetMaterialID(string name)
		{
			return name.ToLower() switch
			{
				"black" => 0, 
				"white" => 1, 
				"boots" => 2, 
				"spots" => 3, 
				"orange" => 4, 
				"stripes" => 5, 
				_ => -1, 
			};
		}

		private void PatchNetcode()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void AddNeedyCatsToNetworkManager(GameNetworkManager __instance)
		{
			((Component)__instance).GetComponent<NetworkManager>().AddNetworkPrefab(Assets.MainAssetBundle.LoadAsset<GameObject>("Cat.prefab"));
			mls.LogInfo((object)"Added Needy Cats prefab to Network Manager.");
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void AddNeedyCatsToItems(StartOfRound __instance)
		{
			Item item = Assets.MainAssetBundle.LoadAsset<Item>("CatItem");
			if (!__instance.allItemsList.itemsList.Contains(item))
			{
				__instance.allItemsList.itemsList.Add(item);
			}
			mls.LogInfo((object)"Added Needy Cats to items list.");
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPrefix]
		private static void AddNeedyCatsToAllLevels(StartOfRound __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Item item = Assets.MainAssetBundle.LoadAsset<Item>("CatItem");
			SpawnableItemWithRarity val = new SpawnableItemWithRarity();
			val.rarity = spawnRate.Value;
			val.spawnableItem = item;
			SelectableLevel[] levels = __instance.levels;
			foreach (SelectableLevel val2 in levels)
			{
				if (val2.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)item))
				{
					return;
				}
				val2.spawnableScrap.Add(val);
			}
			mls.LogInfo((object)"Added Needy Cats to all levels.");
		}

		[HarmonyPatch(typeof(HoarderBugAI), "GrabTargetItemIfClose")]
		[HarmonyPrefix]
		private static bool GrabTargetItemIfClose(HoarderBugAI __instance)
		{
			//IL_003c: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			float num = ((__instance.targetItem is NeedyCatProp) ? 1f : 0.75f);
			if ((Object)(object)__instance.targetItem != (Object)null && __instance.heldItem == null && Vector3.Distance(((Component)__instance).transform.position, ((Component)__instance.targetItem).transform.position) < num)
			{
				if (!((EnemyAI)__instance).SetDestinationToPosition(__instance.nestPosition, true))
				{
					__instance.nestPosition = ((EnemyAI)__instance).ChooseClosestNodeToPosition(((Component)__instance).transform.position, false, 0).position;
					((EnemyAI)__instance).SetDestinationToPosition(__instance.nestPosition, false);
				}
				NetworkObject component = ((Component)__instance.targetItem).GetComponent<NetworkObject>();
				((EnemyAI)__instance).SwitchToBehaviourStateOnLocalClient(1);
				__instance.GrabItem(component);
				__instance.sendingGrabOrDropRPC = true;
				__instance.GrabItemServerRpc(NetworkObjectReference.op_Implicit(component));
				return true;
			}
			return false;
		}

		[HarmonyPatch(typeof(NeedyCatProp), "Awake")]
		[HarmonyPrefix]
		private static void AddNeedyCatsNames(NeedyCatProp __instance)
		{
			__instance.CatNames = catNames.ToArray();
		}
	}
}

mods/LethalOrg-ProgressiveDeadline-2.0.0/BepInEx/plugins/ProgressiveDeadline.dll

Decompiled 10 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ProgressiveDeadline
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ProgressiveDeadline";

		public const string PLUGIN_NAME = "ProgressiveDeadline";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ProgressiveDeadlineMod
{
	public class Utils
	{
		public static float dailyIncrease(float runCount, AnimationCurve randomizerCurve)
		{
			float value = ProgressiveDeadlineMod.minScrapIncrease.Value;
			float value2 = ProgressiveDeadlineMod.minScrapIncreaseSteepness.Value;
			if (ProgressiveDeadlineMod.useLinearAlgorithm.Value)
			{
				return value;
			}
			float num = randomizerCurve.Evaluate(Random.Range(0f, 1f)) + 1f;
			float num2 = 1f + runCount * (runCount / value2);
			return value * num2 * num;
		}

		public static float buyingRate(TimeOfDay timeOfDay)
		{
			int deadlineDaysAmount = timeOfDay.quotaVariables.deadlineDaysAmount;
			int deadlineDays = getDeadlineDays(timeOfDay);
			ProgressiveDeadlineMod.Instance.mls.LogInfo((object)$"AQ {deadlineDaysAmount} {deadlineDays}");
			if (deadlineDays == 0)
			{
				return 1f;
			}
			float num = 1f / (float)deadlineDaysAmount;
			return (1f - num) / (float)deadlineDaysAmount * (float)(deadlineDaysAmount - deadlineDays) + num;
		}

		public static float getTotalTime(TimeOfDay timeOfDay)
		{
			float num = timeOfDay.totalTime;
			if (num == 0f)
			{
				num = timeOfDay.lengthOfHours * (float)timeOfDay.numberOfHours;
			}
			return num;
		}

		public static float getTimeUntilDeadline(TimeOfDay timeOfDay, float days)
		{
			return days * getTotalTime(timeOfDay);
		}

		public static int getDeadlineDays(TimeOfDay timeOfDay)
		{
			return (int)(timeOfDay.timeUntilDeadline / getTotalTime(timeOfDay));
		}
	}
	[BepInPlugin("LethalOrg.ProgressiveDeadline", "Progressive Deadline", "2.0.0")]
	public class ProgressiveDeadlineMod : BaseUnityPlugin
	{
		private const string modGUID = "LethalOrg.ProgressiveDeadline";

		private const string modName = "Progressive Deadline";

		private const string modVersion = "2.0.0";

		private readonly Harmony harmony = new Harmony("LethalOrg.ProgressiveDeadline");

		public static ProgressiveDeadlineMod Instance;

		internal static ConfigEntry<float> minimumDays;

		internal static ConfigEntry<float> maximumDays;

		internal static ConfigEntry<float> minDailyScrap;

		internal static ConfigEntry<bool> useLinearAlgorithm;

		internal static ConfigEntry<float> minScrapIncrease;

		internal static ConfigEntry<float> minScrapIncreaseSteepness;

		internal ManualLogSource mls;

		internal void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("Progressive Deadline");
			mls.LogInfo((object)"Progressive deadline started");
			minimumDays = ((BaseUnityPlugin)this).Config.Bind<float>("Customizable Values", "Minimum Deadline", 2f, "This is the minimum deadline you will have.");
			maximumDays = ((BaseUnityPlugin)this).Config.Bind<float>("Customizable Values", "Maximum Deadline", float.MaxValue, "This is the maximum deadline you will have.");
			minDailyScrap = ((BaseUnityPlugin)this).Config.Bind<float>("Customizable Values", "Minimum Daily ScrapValue", 100f, "Minimum scrap value you can achieve per day. This will ignore the calculation for daily scrap if it's below this number. (Default: 100f)");
			minScrapIncrease = ((BaseUnityPlugin)this).Config.Bind<float>("Customizable Values", "Base Minimum Scrap Value Increase", 30f, "This is the minimum amount the minimum scrap value will increase every time a quota is complete. (Default: 30f)");
			minScrapIncreaseSteepness = ((BaseUnityPlugin)this).Config.Bind<float>("Customizable Values", "Incremental Daily Value Steepness", 200f, "Defines the Steepness of the minimum incremental daily value scalling with each completed quota. (Default: 200f)");
			useLinearAlgorithm = ((BaseUnityPlugin)this).Config.Bind<bool>("Use linear calculations for minimum daily scrap", "Static Base Minimum Scrap", false, "If set to true, the 'Base Minimum Scrap Value Increase' will remain fixed and will not scale based on 'Incremental Daily Value Steepness' and quota completion. (Default: false)");
			harmony.PatchAll();
		}
	}
}
namespace ProgressiveDeadlineMod.Patches
{
	[HarmonyPatch(typeof(TimeOfDay))]
	[HarmonyPatch("Awake")]
	public static class QuotaSettingsPatch
	{
		[HarmonyPostfix]
		public static void SetStartingDeadline(TimeOfDay __instance)
		{
			if (__instance.quotaVariables != null && ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost)
			{
				string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
				float value = ProgressiveDeadlineMod.minimumDays.Value;
				float days = ES3.Load<float>("deadlineAmount", currentSaveFileName, value);
				__instance.timeUntilDeadline = Utils.getTimeUntilDeadline(__instance, days);
				__instance.SyncTimeClientRpc(__instance.globalTime, (int)__instance.timeUntilDeadline);
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
	public class ResetSavedValuesPatch
	{
		[HarmonyPrefix]
		public static void ResetSaves(GameNetworkManager __instance)
		{
			if (((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost)
			{
				TimeOfDay val = Object.FindObjectOfType<TimeOfDay>();
				string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
				float value = ProgressiveDeadlineMod.minimumDays.Value;
				float value2 = ProgressiveDeadlineMod.minDailyScrap.Value;
				val.timeUntilDeadline = Utils.getTimeUntilDeadline(val, value);
				val.SyncTimeClientRpc(val.globalTime, (int)val.timeUntilDeadline);
				ES3.Save<float>("deadlineAmount", value, currentSaveFileName);
				ES3.Save<float>("previousDaily", value2, currentSaveFileName);
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
	public class ProfitQuotaPatch
	{
		[HarmonyPostfix]
		private static void ProgressiveDeadline(TimeOfDay __instance)
		{
			if (!((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost)
			{
				ProgressiveDeadlineMod.Instance.mls.LogInfo((object)"You're not the host.");
				return;
			}
			float value = ProgressiveDeadlineMod.minimumDays.Value;
			float value2 = ProgressiveDeadlineMod.maximumDays.Value;
			float value3 = ProgressiveDeadlineMod.minDailyScrap.Value;
			string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
			float num = __instance.totalTime;
			float runCount = __instance.timesFulfilledQuota;
			AnimationCurve randomizerCurve = __instance.quotaVariables.randomizerCurve;
			float num2 = ES3.Load<float>("previousDaily", currentSaveFileName, value3);
			num2 += Utils.dailyIncrease(runCount, randomizerCurve);
			float num3 = Mathf.Clamp(Mathf.Ceil((float)__instance.profitQuota / num2), value, value2);
			ES3.Save<float>("previousDaily", num2, currentSaveFileName);
			ES3.Save<float>("deadlineAmount", num3, currentSaveFileName);
			__instance.timeUntilDeadline = num * num3;
			TimeOfDay.Instance.SyncTimeClientRpc(__instance.globalTime, (int)__instance.timeUntilDeadline);
			ProgressiveDeadlineMod.Instance.mls.LogInfo((object)$"You're host, new deadline: {num3}");
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "SyncTimeClientRpc")]
	public class DeadlineDaysAmountSyncPatch
	{
		[HarmonyPostfix]
		private static void deadlineSync(TimeOfDay __instance)
		{
			int deadlineDays = Utils.getDeadlineDays(__instance);
			if (__instance.totalTime == 0f)
			{
				__instance.quotaVariables.deadlineDaysAmount = deadlineDays;
			}
			else if (deadlineDays > __instance.quotaVariables.deadlineDaysAmount)
			{
				__instance.quotaVariables.deadlineDaysAmount = deadlineDays;
				StartOfRound.Instance.companyBuyingRate = Utils.buyingRate(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "SetBuyingRateForDay")]
	public class BuyingRatePatch
	{
		[HarmonyPostfix]
		public static void SetBuyingRate(TimeOfDay __instance)
		{
			StartOfRound.Instance.companyBuyingRate = Utils.buyingRate(__instance);
		}
	}
}

mods/matsuura-HealthMetrics-1.0.2/HealthMetrics.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HealthMetrics")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HealthMetrics")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("eba7b111-51e5-4353-807d-1268e6290901")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HealthMetrics
{
	[BepInPlugin("Matsuura.HealthMetrics", "HealthMetrics", "1.0.0")]
	public class HealthMetricsBase : BaseUnityPlugin
	{
		private const string modGUID = "Matsuura.HealthMetrics";

		private const string modName = "HealthMetrics";

		private const string modVersion = "1.0.0";

		private readonly Harmony _harmony = new Harmony("Matsuura.HealthMetrics");

		private static HealthMetricsBase _instance;

		private static ManualLogSource _logSource;

		internal void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
			}
			if (_logSource == null)
			{
				_logSource = Logger.CreateLogSource("Matsuura.HealthMetrics");
			}
			_harmony.PatchAll();
			_logSource.LogInfo((object)"HealthMetrics Awake");
		}

		internal static void Log(string message)
		{
			if (_logSource != null)
			{
				_logSource.LogInfo((object)message);
			}
		}

		internal static void LogD(string message)
		{
			if (_logSource != null)
			{
				_logSource.LogDebug((object)message);
			}
		}
	}
}
namespace HealthMetrics.Patches
{
	[HarmonyPatch(typeof(HUDManager))]
	internal class HealthHUDPatches
	{
		private static TextMeshProUGUI _healthText;

		private static readonly string DefaultValueHealthText = " ¤";

		public static int _oldValuehealthValueForUpdater = 0;

		public static int _healthValueForUpdater = 100;

		private static readonly Color _healthyColor = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue));

		private static readonly Color _criticalHealthColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)0, (byte)0, byte.MaxValue));

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start(ref HUDManager __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("HealthHUDDisplay");
			val.AddComponent<RectTransform>();
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
			((Transform)rectTransform).SetParent(((Component)__instance.PTTIcon).transform, false);
			rectTransform.anchoredPosition = new Vector2(8f, -57f);
			((TMP_Text)obj).font = ((TMP_Text)__instance.controlTipLines[0]).font;
			((TMP_Text)obj).fontSize = 16f;
			((TMP_Text)obj).text = "100";
			((Graphic)obj).color = _healthyColor;
			((TMP_Text)obj).overflowMode = (TextOverflowModes)0;
			((Behaviour)obj).enabled = true;
			_healthText = obj;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void Update()
		{
			//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_healthText != (Object)null && _healthValueForUpdater != _oldValuehealthValueForUpdater)
			{
				_oldValuehealthValueForUpdater = _healthValueForUpdater;
				if (_healthValueForUpdater > 0)
				{
					((TMP_Text)_healthText).text = _healthValueForUpdater.ToString().PadLeft((_healthValueForUpdater < 10) ? 2 : 3, ' ');
				}
				else
				{
					((TMP_Text)_healthText).text = DefaultValueHealthText;
				}
				double percentage = (double)_healthValueForUpdater / 100.0;
				((Graphic)_healthText).color = ColorInterpolation(_criticalHealthColor, _healthyColor, percentage);
			}
		}

		public static int LinearInterpolation(int start, int end, double percentage)
		{
			return start + (int)Math.Round(percentage * (double)(end - start));
		}

		public static Color ColorInterpolation(Color start, Color end, double percentage)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			return new Color(hexToFloat(LinearInterpolation(floatToHex(start.r), floatToHex(end.r), percentage)), hexToFloat(LinearInterpolation(floatToHex(start.g), floatToHex(end.g), percentage)), hexToFloat(LinearInterpolation(floatToHex(start.b), floatToHex((int)end.b), percentage)), 1f);
		}

		public static float hexToFloat(int hex)
		{
			return (float)hex / 255f;
		}

		public static int floatToHex(float f)
		{
			return (int)f * 255;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("LateUpdate")]
		private static void LateUpdate_Prefix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject))
			{
				HealthHUDPatches._healthValueForUpdater = ((__instance.health >= 0) ? __instance.health : 0);
			}
		}
	}
}

mods/Mhz-MoreHead-1.2.5/MoreHead.dll

Decompiled 10 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using MoreCompany.Cosmetics;
using MoreCompany.Utils;
using MoreHead.Cosmetics;
using MoreHead.MoreScript;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MoreHead")]
[assembly: AssemblyDescription("A head mod")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreHead")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("011E6CD3-31C5-43C5-8681-EC192737BD7F")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MoreHead
{
	[BepInPlugin("Mhz.MoreHead", "MoreHead", "1.2.5")]
	public class PluginOne : BaseUnityPlugin
	{
		private const string PluginGuid = "Mhz.MoreHead";

		private const string PluginName = "MoreHead";

		private const string PluginVersion = "1.2.5";

		private static Harmony _harmony;

		private void Awake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (_harmony == null)
			{
				_harmony = new Harmony("Mhz.MoreHead");
				_harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreHead OK");
				Init();
			}
		}

		private void Init()
		{
			List<StreamCosmeticGeneric> cosmetics = new List<StreamCosmeticGeneric>
			{
				new YanCao(),
				new FanYanCao(),
				new MaoTou(),
				new Zhutou(),
				new Caomaoer(),
				new Dalalala(),
				new Heshuimao(),
				new Xiguamao(),
				new PaydayMask(),
				new Shoulianer(),
				new Shoubiaoer(),
				new Heijiaobu(),
				new Shouhuaner(),
				new Mianzhaoer(),
				new Koushuibudou(),
				new Gegedetou(),
				new Yashuaer(),
				new Yuguagua(),
				new Doulimaoer_1(),
				new Doulimaoer_2(),
				new Baonuanmao(),
				new Wushidaoer(),
				new Qingwashubaoer(),
				new Maoerbao(),
				new Tanxianbao(),
				new Siduiyou(),
				new Manaoke()
			};
			LoadAssets(cosmetics);
		}

		private void LoadAssets(IEnumerable<StreamCosmeticGeneric> cosmetics)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreHead Asset OK");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			foreach (StreamCosmeticGeneric cosmetic in cosmetics)
			{
				AssetBundle val = BundleUtilities.LoadBundleFromInternalAssembly(cosmetic.StreamingPath, executingAssembly);
				GameObject val2 = AssetBundleExtension.LoadPersistentAsset<GameObject>(val, ((CosmeticGeneric)cosmetic).gameObjectPath);
				if ((Object)(object)val2 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to find GameObject for cosmetic '" + ((CosmeticGeneric)cosmetic).cosmeticId + "' at path '" + ((CosmeticGeneric)cosmetic).gameObjectPath + "'"));
					continue;
				}
				if (((CosmeticGeneric)cosmetic).cosmeticId == "morehead.fanxiangyan")
				{
					GameObject gameObject = ((Component)val2.transform.Find("cigarette/yan/yanlizi")).gameObject;
					if ((Object)(object)gameObject == (Object)null)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)"No fanxiangyanlizi!");
					}
					else
					{
						gameObject.AddComponent<Huanse>();
						((BaseUnityPlugin)this).Logger.LogWarning((object)"fanxiangyanlizi ok.");
					}
				}
				Texture2D val3 = AssetBundleExtension.LoadPersistentAsset<Texture2D>(val, ((CosmeticGeneric)cosmetic).textureIconPath);
				if ((Object)(object)val3 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to find icon Texture2D for cosmetic '" + ((CosmeticGeneric)cosmetic).cosmeticId + " at path '" + ((CosmeticGeneric)cosmetic).textureIconPath + "'"));
				}
				else
				{
					CosmeticInstance val4 = val2.AddComponent<CosmeticInstance>();
					val4.cosmeticId = ((CosmeticGeneric)cosmetic).cosmeticId;
					val4.icon = val3;
					val4.cosmeticType = ((CosmeticGeneric)cosmetic).cosmeticType;
					CosmeticRegistry.cosmeticInstances.Add(((CosmeticGeneric)cosmetic).cosmeticId, val4);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Successfully loaded cosmetic: " + ((CosmeticGeneric)cosmetic).cosmeticId));
				}
			}
		}
	}
}
namespace MoreHead.Cosmetics
{
	public abstract class StreamCosmeticGeneric : CosmeticGeneric
	{
		public virtual string StreamingPath => string.Empty;
	}
	public class YanCao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yan";

		public override string gameObjectPath => "Assets/MoreHead/Yan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/YanTu.png";

		public override string StreamingPath => "morehead.more.yan1";
	}
	public class FanYanCao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.fanxiangyan";

		public override string gameObjectPath => "Assets/MoreHead/Fanxiangyan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Fanxiangyantu.png";

		public override string StreamingPath => "morehead.more.yan2";
	}
	public class MaoTou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.cathead";

		public override string gameObjectPath => "Assets/MoreHead/CatHead.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Cattu.png";

		public override string StreamingPath => "morehead.more.cathead";
	}
	public class Zhutou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.pighead";

		public override string gameObjectPath => "Assets/MoreHead/PigHead.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Zhutu.png";

		public override string StreamingPath => "morehead.more.pighead";
	}
	public class Caomaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.caomao";

		public override string gameObjectPath => "Assets/MoreHead/CaoMao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Caomaotu.png";

		public override string StreamingPath => "morehead.more.caomao";
	}
	public class Dalalala : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.xiangsuyanjing";

		public override string gameObjectPath => "Assets/MoreHead/YanJingEr.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Xiangsuyanjingtu.png";

		public override string StreamingPath => "morehead.more.yanjinger";
	}
	public class Heshuimao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.shuimao";

		public override string gameObjectPath => "Assets/MoreHead/ShuiMao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Shuimaotu.png";

		public override string StreamingPath => "morehead.more.shuimaoer";
	}
	public class Xiguamao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.xiguatou";

		public override string gameObjectPath => "Assets/MoreHead/XiguaTou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Xiguatu.png";

		public override string StreamingPath => "morehead.more.xiguanaodai";
	}
	public class PaydayMask : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.dallas";

		public override string gameObjectPath => "Assets/MoreHead/DallasMask.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Masktu.png";

		public override string StreamingPath => "morehead.more.paydaytou";
	}
	public class Shoulianer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.shoulian";

		public override string gameObjectPath => "Assets/MoreHead/Shoulian.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Shouliantu.png";

		public override string StreamingPath => "morehead.more.shoulian";
	}
	public class Shoubiaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.biao";

		public override string gameObjectPath => "Assets/MoreHead/Biao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Biaotu.png";

		public override string StreamingPath => "morehead.more.shoubiao";
	}
	public class Heijiaobu : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.heiweijin";

		public override string gameObjectPath => "Assets/MoreHead/Heiweijin.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Heiweijintu.png";

		public override string StreamingPath => "morehead.more.dongdianjiaobu";
	}
	public class Shouhuaner : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.jinshouhuan";

		public override string gameObjectPath => "Assets/MoreHead/Jinshouhuan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Jinshouhuantu.png";

		public override string StreamingPath => "morehead.more.jinshouhuan";
	}
	public class Mianzhaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.mianzhao";

		public override string gameObjectPath => "Assets/MoreHead/Mianzhao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Mianzhaotu.png";

		public override string StreamingPath => "morehead.more.mianzhao";
	}
	public class Koushuibudou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.koushuibu";

		public override string gameObjectPath => "Assets/MoreHead/Koushuibu.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Koushuibutu.png";

		public override string StreamingPath => "morehead.more.koushuibudou";
	}
	public class Gegedetou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.kunkuntou";

		public override string gameObjectPath => "Assets/MoreHead/Kuntou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Kuntoutu.png";

		public override string StreamingPath => "morehead.more.jigetou";
	}
	public class Yashuaer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yashua";

		public override string gameObjectPath => "Assets/MoreHead/Yashuashuaya.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Yashuatu.png";

		public override string StreamingPath => "morehead.more.shuayaya";
	}
	public class Yuguagua : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yuguaqi";

		public override string gameObjectPath => "Assets/MoreHead/Yugua.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Yuguatu.png";

		public override string StreamingPath => "morehead.more.yuguagua";
	}
	public class Doulimaoer_1 : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.douli1";

		public override string gameObjectPath => "Assets/MoreHead/Doulimao1.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Doulimaotu.png";

		public override string StreamingPath => "morehead.more.doulimao1";
	}
	public class Doulimaoer_2 : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.douli2";

		public override string gameObjectPath => "Assets/MoreHead/Doulimao2.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Doulimaotu.png";

		public override string StreamingPath => "morehead.more.doulimao2";
	}
	public class Baonuanmao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.wula1";

		public override string gameObjectPath => "Assets/MoreHead/Wulamao1.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Wulamaotu.png";

		public override string StreamingPath => "morehead.more.wulamao1";
	}
	public class Wushidaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.dao2077";

		public override string gameObjectPath => "Assets/MoreHead/Wushidao2077.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Dao2077tu.png";

		public override string StreamingPath => "morehead.more.dao2077";
	}
	public class Qingwashubaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.wabao";

		public override string gameObjectPath => "Assets/MoreHead/Qingwashubao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Wabeibaotu.png";

		public override string StreamingPath => "morehead.more.qingwabaobao";
	}
	public class Maoerbao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.maoerbao";

		public override string gameObjectPath => "Assets/MoreHead/Maoerbao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Maoerbaotu.png";

		public override string StreamingPath => "morehead.more.maoerbao";
	}
	public class Tanxianbao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.tanxianbao";

		public override string gameObjectPath => "Assets/MoreHead/Tanxianbao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Tanxianbaotu.png";

		public override string StreamingPath => "morehead.more.tanxianbao";
	}
	public class Siduiyou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.dongdesiduiyou";

		public override string gameObjectPath => "Assets/MoreHead/Siduiyou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Siduiyoutu.png";

		public override string StreamingPath => "morehead.more.dongdesiduiyou";
	}
	public class Manaoke : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.matou";

		public override string gameObjectPath => "Assets/MoreHead/Matou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Matoutu.png";

		public override string StreamingPath => "morehead.more.matou";
	}
}
namespace MoreHead.MoreScript
{
	public class Huanse : MonoBehaviour
	{
		private ParticleSystem _particle;

		private void Start()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			_particle = ((Component)this).GetComponent<ParticleSystem>();
			if ((Object)(object)_particle == (Object)null)
			{
				Debug.LogError((object)"NO ParticleSystem.");
				return;
			}
			MainModule main = _particle.main;
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "MainMenu")
			{
				Color val = default(Color);
				((Color)(ref val))..ctor(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val);
				PlayerPrefs.SetString("SavedColor", ColorUtility.ToHtmlStringRGB(val));
				PlayerPrefs.Save();
			}
			else
			{
				string @string = PlayerPrefs.GetString("SavedColor", "");
				if (!string.IsNullOrEmpty(@string))
				{
					@string = "#" + @string;
					Color val2 = default(Color);
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(ColorUtility.TryParseHtmlString(@string, ref val2) ? val2 : Color.yellow);
				}
			}
			MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
			Debug.LogWarning((object)((MinMaxGradient)(ref startColor)).color);
		}
	}
}

mods/Ozone-Runtime_Netcode_Patcher-0.2.5/NicholaScott.BepInEx.RuntimeNetcodeRPCValidator.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("NicholaScott.BepInEx.RuntimeNetcodeRPCValidator")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.5.0")]
[assembly: AssemblyInformationalVersion("0.2.5+6e2f89b3631ae55d2f51a00ccfd3f20fec9d2372")]
[assembly: AssemblyProduct("RuntimeNetcodeRPCValidator")]
[assembly: AssemblyTitle("NicholaScott.BepInEx.RuntimeNetcodeRPCValidator")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace RuntimeNetcodeRPCValidator
{
	public class AlreadyRegisteredException : Exception
	{
		public AlreadyRegisteredException(string PluginGUID)
			: base("Can't register plugin " + PluginGUID + " until the other instance of NetcodeValidator is Disposed of!")
		{
		}
	}
	public class InvalidPluginGuidException : Exception
	{
		public InvalidPluginGuidException(string pluginGUID)
			: base("Can't patch plugin " + pluginGUID + " because it doesn't exist!")
		{
		}
	}
	public class NotNetworkBehaviourException : Exception
	{
		public NotNetworkBehaviourException(Type type)
			: base("Netcode Runtime RPC Validator tried to NetcodeValidator.Patch type " + type.Name + " that doesn't inherit from NetworkBehaviour!")
		{
		}
	}
	public class MustCallFromDeclaredTypeException : Exception
	{
		public MustCallFromDeclaredTypeException()
			: base("Netcode Runtime RPC Validator tried to run NetcodeValidator.PatchAll from a delegate! You must call PatchAll from a declared type.")
		{
		}
	}
	public static class FastBufferExtensions
	{
		private const BindingFlags BindingAll = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static void WriteSystemSerializable(this FastBufferWriter fastBufferWriter, object serializable)
		{
			//IL_0025: 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)
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			binaryFormatter.Serialize(memoryStream, serializable);
			byte[] array = memoryStream.ToArray();
			int num = array.Length;
			((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			((FastBufferWriter)(ref fastBufferWriter)).WriteBytes(array, -1, 0);
		}

		private static void ReadSystemSerializable(this FastBufferReader fastBufferReader, out object serializable)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			byte[] buffer = new byte[num];
			((FastBufferReader)(ref fastBufferReader)).ReadBytes(ref buffer, num, 0);
			using MemoryStream memoryStream = new MemoryStream(buffer);
			memoryStream.Seek(0L, SeekOrigin.Begin);
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			serializable = binaryFormatter.Deserialize(memoryStream);
		}

		private static void WriteNetcodeSerializable(this FastBufferWriter fastBufferWriter, object networkSerializable)
		{
			//IL_0010: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, -1);
			try
			{
				BufferSerializer<BufferSerializerWriter> val2 = default(BufferSerializer<BufferSerializerWriter>);
				val2..ctor(new BufferSerializerWriter(val));
				object obj = ((networkSerializable is INetworkSerializable) ? networkSerializable : null);
				if (obj != null)
				{
					((INetworkSerializable)obj).NetworkSerialize<BufferSerializerWriter>(val2);
				}
				byte[] array = ((FastBufferWriter)(ref val)).ToArray();
				int num = array.Length;
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref fastBufferWriter)).WriteBytes(array, -1, 0);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void ReadNetcodeSerializable(this FastBufferReader fastBufferReader, Type type, out object serializable)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			byte[] array = new byte[num];
			((FastBufferReader)(ref fastBufferReader)).ReadBytes(ref array, num, 0);
			FastBufferReader val = default(FastBufferReader);
			((FastBufferReader)(ref val))..ctor(array, (Allocator)2, -1, 0);
			try
			{
				BufferSerializer<BufferSerializerReader> val2 = default(BufferSerializer<BufferSerializerReader>);
				val2..ctor(new BufferSerializerReader(val));
				serializable = Activator.CreateInstance(type);
				object obj = serializable;
				object obj2 = ((obj is INetworkSerializable) ? obj : null);
				if (obj2 != null)
				{
					((INetworkSerializable)obj2).NetworkSerialize<BufferSerializerReader>(val2);
				}
			}
			finally
			{
				((IDisposable)(FastBufferReader)(ref val)).Dispose();
			}
		}

		public static void WriteMethodInfoAndParameters(this FastBufferWriter fastBufferWriter, MethodBase methodInfo, object[] args)
		{
			//IL_001f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe(methodInfo.Name, false);
			ParameterInfo[] parameters = methodInfo.GetParameters();
			int num = parameters.Length;
			((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref num, default(ForPrimitives));
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				object obj = args[i];
				bool flag = obj == null || parameterInfo.ParameterType == typeof(ServerRpcParams) || parameterInfo.ParameterType == typeof(ClientRpcParams);
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					continue;
				}
				if (parameterInfo.ParameterType.GetInterfaces().Contains(typeof(INetworkSerializable)))
				{
					fastBufferWriter.WriteNetcodeSerializable(obj);
					continue;
				}
				if (parameterInfo.ParameterType.IsSerializable)
				{
					fastBufferWriter.WriteSystemSerializable(obj);
					continue;
				}
				throw new SerializationException(TextHandler.ObjectNotSerializable(parameterInfo));
			}
		}

		public static MethodInfo ReadMethodInfoAndParameters(this FastBufferReader fastBufferReader, Type methodDeclaringType, ref object[] args)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			string name = default(string);
			((FastBufferReader)(ref fastBufferReader)).ReadValueSafe(ref name, false);
			int num = default(int);
			((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			MethodInfo method = methodDeclaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (num != method?.GetParameters().Length)
			{
				throw new Exception(TextHandler.InconsistentParameterCount(method, num));
			}
			bool flag = default(bool);
			for (int i = 0; i < num; i++)
			{
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					continue;
				}
				ParameterInfo parameterInfo = method.GetParameters()[i];
				object serializable;
				if (parameterInfo.ParameterType.GetInterfaces().Contains(typeof(INetworkSerializable)))
				{
					fastBufferReader.ReadNetcodeSerializable(parameterInfo.ParameterType, out serializable);
				}
				else
				{
					if (!parameterInfo.ParameterType.IsSerializable)
					{
						throw new SerializationException(TextHandler.ObjectNotSerializable(parameterInfo));
					}
					fastBufferReader.ReadSystemSerializable(out serializable);
				}
				args[i] = serializable;
			}
			return method;
		}
	}
	public sealed class NetcodeValidator : IDisposable
	{
		private static readonly List<string> AlreadyRegistered = new List<string>();

		internal const string TypeCustomMessageHandlerPrefix = "Net";

		private static List<(NetcodeValidator validator, Type custom, Type native)> BoundNetworkObjects { get; } = new List<(NetcodeValidator, Type, Type)>();


		private List<string> CustomMessageHandlers { get; }

		private Harmony Patcher { get; }

		public string PluginGuid { get; }

		internal static event Action<NetcodeValidator, Type> AddedNewBoundBehaviour;

		private event Action<string> AddedNewCustomMessageHandler;

		public NetcodeValidator(string pluginGuid)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (!Chainloader.PluginInfos.TryGetValue(pluginGuid, out var _))
			{
				throw new InvalidPluginGuidException(pluginGuid);
			}
			if (AlreadyRegistered.Contains(pluginGuid))
			{
				throw new AlreadyRegisteredException(pluginGuid);
			}
			AlreadyRegistered.Add(pluginGuid);
			PluginGuid = pluginGuid;
			CustomMessageHandlers = new List<string>();
			Patcher = new Harmony(pluginGuid + "NicholaScott.BepInEx.RuntimeNetcodeRPCValidator");
			Plugin.NetworkManagerInitialized += NetworkManagerInitialized;
			Plugin.NetworkManagerShutdown += NetworkManagerShutdown;
		}

		internal static void TryLoadRelatedComponentsInOrder(NetworkBehaviour __instance, MethodBase __originalMethod)
		{
			foreach (var item in from obj in BoundNetworkObjects
				where obj.native == __originalMethod.DeclaringType
				select obj into it
				orderby it.validator.PluginGuid
				select it)
			{
				Plugin.Logger.LogInfo((object)TextHandler.CustomComponentAddedToExistingObject(item, __originalMethod));
				Component obj2 = ((Component)__instance).gameObject.AddComponent(item.custom);
				((NetworkBehaviour)(object)((obj2 is NetworkBehaviour) ? obj2 : null)).SyncWithNetworkObject();
			}
		}

		private bool Patch(MethodInfo rpcMethod, out bool isServerRpc, out bool isClientRpc)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			isServerRpc = ((MemberInfo)rpcMethod).GetCustomAttributes<ServerRpcAttribute>().Any();
			isClientRpc = ((MemberInfo)rpcMethod).GetCustomAttributes<ClientRpcAttribute>().Any();
			bool flag = rpcMethod.Name.EndsWith("ServerRpc");
			bool flag2 = rpcMethod.Name.EndsWith("ClientRpc");
			if (!isClientRpc && !isServerRpc && !flag2 && !flag)
			{
				return false;
			}
			if ((!isServerRpc && flag) || (!isClientRpc && flag2))
			{
				Plugin.Logger.LogError((object)TextHandler.MethodLacksRpcAttribute(rpcMethod));
				return false;
			}
			if ((isServerRpc && !flag) || (isClientRpc && !flag2))
			{
				Plugin.Logger.LogError((object)TextHandler.MethodLacksSuffix(rpcMethod));
				return false;
			}
			Patcher.Patch((MethodBase)rpcMethod, new HarmonyMethod(typeof(NetworkBehaviourExtensions), "MethodPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		public void BindToPreExistingObjectByBehaviour<TCustomBehaviour, TNativeBehaviour>() where TCustomBehaviour : NetworkBehaviour where TNativeBehaviour : NetworkBehaviour
		{
			if (Object.op_Implicit((Object)(object)NetworkManager.Singleton) && (NetworkManager.Singleton.IsListening || NetworkManager.Singleton.IsConnectedClient))
			{
				Plugin.Logger.LogError((object)TextHandler.PluginTriedToBindToPreExistingObjectTooLate(this, typeof(TCustomBehaviour), typeof(TNativeBehaviour)));
			}
			else
			{
				OnAddedNewBoundBehaviour(this, typeof(TCustomBehaviour), typeof(TNativeBehaviour));
			}
		}

		public void Patch(Type netBehaviourTyped)
		{
			if (netBehaviourTyped.BaseType != typeof(NetworkBehaviour))
			{
				throw new NotNetworkBehaviourException(netBehaviourTyped);
			}
			OnAddedNewCustomMessageHandler("Net." + netBehaviourTyped.Name);
			int num = 0;
			int num2 = 0;
			MethodInfo[] methods = netBehaviourTyped.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo rpcMethod in methods)
			{
				if (Patch(rpcMethod, out var isServerRpc, out var isClientRpc))
				{
					num += (isServerRpc ? 1 : 0);
					num2 += (isClientRpc ? 1 : 0);
				}
			}
			Plugin.Logger.LogInfo((object)TextHandler.SuccessfullyPatchedType(netBehaviourTyped, num, num2));
		}

		public void Patch(Assembly assembly)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.BaseType == typeof(NetworkBehaviour))
				{
					Patch(type);
				}
			}
		}

		public void PatchAll()
		{
			Assembly assembly = new StackTrace().GetFrame(1).GetMethod().ReflectedType?.Assembly;
			if (assembly == null)
			{
				throw new MustCallFromDeclaredTypeException();
			}
			Patch(assembly);
		}

		public void UnpatchSelf()
		{
			Plugin.Logger.LogInfo((object)TextHandler.PluginUnpatchedAllRPCs(this));
			Patcher.UnpatchSelf();
		}

		private static void RegisterMessageHandlerWithNetworkManager(string handler)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(handler, new HandleNamedMessageDelegate(NetworkBehaviourExtensions.ReceiveNetworkMessage));
		}

		private void NetworkManagerInitialized()
		{
			AddedNewCustomMessageHandler += RegisterMessageHandlerWithNetworkManager;
			foreach (string customMessageHandler in CustomMessageHandlers)
			{
				RegisterMessageHandlerWithNetworkManager(customMessageHandler);
			}
		}

		private void NetworkManagerShutdown()
		{
			AddedNewCustomMessageHandler -= RegisterMessageHandlerWithNetworkManager;
			foreach (string customMessageHandler in CustomMessageHandlers)
			{
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(customMessageHandler);
			}
		}

		public void Dispose()
		{
			Plugin.NetworkManagerInitialized -= NetworkManagerInitialized;
			Plugin.NetworkManagerShutdown -= NetworkManagerShutdown;
			AlreadyRegistered.Remove(PluginGuid);
			if (Object.op_Implicit((Object)(object)NetworkManager.Singleton))
			{
				NetworkManagerShutdown();
			}
			if (Patcher.GetPatchedMethods().Any())
			{
				UnpatchSelf();
			}
		}

		private void OnAddedNewCustomMessageHandler(string obj)
		{
			CustomMessageHandlers.Add(obj);
			this.AddedNewCustomMessageHandler?.Invoke(obj);
		}

		private static void OnAddedNewBoundBehaviour(NetcodeValidator validator, Type custom, Type native)
		{
			BoundNetworkObjects.Add((validator, custom, native));
			NetcodeValidator.AddedNewBoundBehaviour?.Invoke(validator, native);
		}
	}
	public static class NetworkBehaviourExtensions
	{
		public enum RpcState
		{
			FromUser,
			FromNetworking
		}

		private static RpcState RpcSource;

		public static ClientRpcParams CreateSendToFromReceived(this ServerRpcParams senderId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			ClientRpcParams result = default(ClientRpcParams);
			result.Send = new ClientRpcSendParams
			{
				TargetClientIds = new ulong[1] { senderId.Receive.SenderClientId }
			};
			return result;
		}

		public static void SyncWithNetworkObject(this NetworkBehaviour networkBehaviour)
		{
			if (!networkBehaviour.NetworkObject.ChildNetworkBehaviours.Contains(networkBehaviour))
			{
				networkBehaviour.NetworkObject.ChildNetworkBehaviours.Add(networkBehaviour);
			}
			networkBehaviour.UpdateNetworkProperties();
		}

		private static bool ValidateRPCMethod(NetworkBehaviour networkBehaviour, MethodBase method, RpcState state, out RpcAttribute rpcAttribute)
		{
			bool flag = ((MemberInfo)method).GetCustomAttributes<ServerRpcAttribute>().Any();
			bool flag2 = ((MemberInfo)method).GetCustomAttributes<ClientRpcAttribute>().Any();
			bool num = flag && ((MemberInfo)method).GetCustomAttribute<ServerRpcAttribute>().RequireOwnership;
			rpcAttribute = (RpcAttribute)(flag ? ((object)((MemberInfo)method).GetCustomAttribute<ServerRpcAttribute>()) : ((object)((MemberInfo)method).GetCustomAttribute<ClientRpcAttribute>()));
			if (num && networkBehaviour.OwnerClientId != NetworkManager.Singleton.LocalClientId)
			{
				Plugin.Logger.LogError((object)TextHandler.NotOwnerOfNetworkObject((state == RpcState.FromUser) ? "We" : "Client", method, networkBehaviour.NetworkObject));
				return false;
			}
			if (state == RpcState.FromUser && flag2 && !NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				Plugin.Logger.LogError((object)TextHandler.CantRunClientRpcFromClient(method));
				return false;
			}
			if (state == RpcState.FromUser && !flag && !flag2)
			{
				Plugin.Logger.LogError((object)TextHandler.MethodPatchedButLacksAttributes(method));
				return false;
			}
			if (state == RpcState.FromNetworking && !flag && !flag2)
			{
				Plugin.Logger.LogError((object)TextHandler.MethodPatchedAndNetworkCalledButLacksAttributes(method));
				return false;
			}
			if (state == RpcState.FromNetworking && flag && !networkBehaviour.IsServer && !networkBehaviour.IsHost)
			{
				Plugin.Logger.LogError((object)TextHandler.CantRunServerRpcAsClient(method));
				return false;
			}
			return true;
		}

		private static bool MethodPatchInternal(NetworkBehaviour networkBehaviour, MethodBase method, object[] args)
		{
			//IL_007d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)NetworkManager.Singleton) || (!NetworkManager.Singleton.IsListening && !NetworkManager.Singleton.IsConnectedClient))
			{
				Plugin.Logger.LogError((object)TextHandler.NoNetworkManagerPresentToSendRpc(networkBehaviour));
				return false;
			}
			RpcState rpcSource = RpcSource;
			RpcSource = RpcState.FromUser;
			if (rpcSource == RpcState.FromNetworking)
			{
				return true;
			}
			if (!ValidateRPCMethod(networkBehaviour, method, rpcSource, out var rpcAttribute))
			{
				return false;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor((method.GetParameters().Length + 1) * 128, (Allocator)2, -1);
			ulong networkObjectId = networkBehaviour.NetworkObjectId;
			((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
			ushort networkBehaviourId = networkBehaviour.NetworkBehaviourId;
			((FastBufferWriter)(ref val)).WriteValueSafe<ushort>(ref networkBehaviourId, default(ForPrimitives));
			val.WriteMethodInfoAndParameters(method, args);
			string text = new StringBuilder("Net").Append(".").Append(method.DeclaringType.Name).ToString();
			NetworkDelivery val2 = (NetworkDelivery)(((int)rpcAttribute.Delivery == 0) ? 2 : 0);
			if (rpcAttribute is ServerRpcAttribute)
			{
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(text, 0uL, val, val2);
			}
			else
			{
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length != 0 && parameters[^1].ParameterType == typeof(ClientRpcParams))
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(text, ((ClientRpcParams)args[^1]).Send.TargetClientIds, val, val2);
				}
				else
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(text, val, val2);
				}
			}
			return false;
		}

		internal static void ReceiveNetworkMessage(ulong sender, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			ulong key = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
			ushort num = default(ushort);
			((FastBufferReader)(ref reader)).ReadValueSafe<ushort>(ref num, default(ForPrimitives));
			int position = ((FastBufferReader)(ref reader)).Position;
			string text = default(string);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
			((FastBufferReader)(ref reader)).Seek(position);
			if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(key, out var value))
			{
				Plugin.Logger.LogError((object)TextHandler.RpcCalledBeforeObjectSpawned());
				return;
			}
			NetworkBehaviour networkBehaviourAtOrderIndex = value.GetNetworkBehaviourAtOrderIndex(num);
			MethodInfo method = ((object)networkBehaviourAtOrderIndex).GetType().GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			RpcAttribute rpcAttribute;
			if (method == null)
			{
				Plugin.Logger.LogError((object)TextHandler.NetworkCalledNonExistentMethod(networkBehaviourAtOrderIndex, text));
			}
			else if (ValidateRPCMethod(networkBehaviourAtOrderIndex, method, RpcState.FromNetworking, out rpcAttribute))
			{
				RpcSource = RpcState.FromNetworking;
				ParameterInfo[] parameters = method.GetParameters();
				bool num2 = rpcAttribute is ServerRpcAttribute && parameters.Length != 0 && parameters[^1].ParameterType == typeof(ServerRpcParams);
				object[] args = null;
				if (parameters.Length != 0)
				{
					args = new object[parameters.Length];
				}
				reader.ReadMethodInfoAndParameters(method.DeclaringType, ref args);
				if (num2)
				{
					args[^1] = (object)new ServerRpcParams
					{
						Receive = new ServerRpcReceiveParams
						{
							SenderClientId = sender
						}
					};
				}
				method.Invoke(networkBehaviourAtOrderIndex, args);
			}
		}

		internal static bool MethodPatch(NetworkBehaviour __instance, MethodBase __originalMethod, object[] __args)
		{
			return MethodPatchInternal(__instance, __originalMethod, __args);
		}
	}
	[BepInPlugin("NicholaScott.BepInEx.RuntimeNetcodeRPCValidator", "RuntimeNetcodeRPCValidator", "0.2.5")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("NicholaScott.BepInEx.RuntimeNetcodeRPCValidator");

		private List<Type> AlreadyPatchedNativeBehaviours { get; } = new List<Type>();


		internal static ManualLogSource Logger { get; private set; }

		public static event Action NetworkManagerInitialized;

		public static event Action NetworkManagerShutdown;

		private void Awake()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			NetcodeValidator.AddedNewBoundBehaviour += NetcodeValidatorOnAddedNewBoundBehaviour;
			_harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkManager), "Initialize", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "OnNetworkManagerInitialized", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkManager), "Shutdown", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "OnNetworkManagerShutdown", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private void NetcodeValidatorOnAddedNewBoundBehaviour(NetcodeValidator validator, Type netBehaviour)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			if (!AlreadyPatchedNativeBehaviours.Contains(netBehaviour))
			{
				AlreadyPatchedNativeBehaviours.Add(netBehaviour);
				MethodBase methodBase = AccessTools.Method(netBehaviour, "Awake", (Type[])null, (Type[])null);
				if (methodBase == null)
				{
					methodBase = AccessTools.Method(netBehaviour, "Start", (Type[])null, (Type[])null);
				}
				if (methodBase == null)
				{
					methodBase = AccessTools.Constructor(netBehaviour, (Type[])null, false);
				}
				Logger.LogInfo((object)TextHandler.RegisteredPatchForType(validator, netBehaviour, methodBase));
				HarmonyMethod val = new HarmonyMethod(typeof(NetcodeValidator), "TryLoadRelatedComponentsInOrder", (Type[])null);
				_harmony.Patch(methodBase, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		protected static void OnNetworkManagerInitialized()
		{
			Plugin.NetworkManagerInitialized?.Invoke();
		}

		protected static void OnNetworkManagerShutdown()
		{
			Plugin.NetworkManagerShutdown?.Invoke();
		}
	}
	internal static class TextHandler
	{
		private const string NoNetworkManagerPresentToSendRpcConst = "NetworkBehaviour {0} tried to send a RPC but the NetworkManager is non-existant!";

		private const string MethodLacksAttributeConst = "Can't patch method {0}.{1} because it lacks a [{2}] attribute.";

		private const string MethodLacksSuffixConst = "Can't patch method {0}.{1} because it's name doesn't end with '{2}'!";

		private const string SuccessfullyPatchedTypeConst = "Patched {0} ServerRPC{1} & {2} ClientRPC{3} on NetworkBehaviour {4}.";

		private const string NotOwnerOfNetworkObjectConst = "{0} tried to run ServerRPC {1} but not the owner of NetworkObject {2}";

		private const string CantRunClientRpcFromClientConst = "Tried to run ClientRpc {0} but we're not a host! You should only call ClientRpc(s) from inside a ServerRpc OR if you've checked you're on the server with IsHost!";

		private const string CantRunServerRpcAsClientConst = "Received message to run ServerRPC {0}.{1} but we're a client!";

		private const string MethodPatchedButLacksAttributesConst = "Rpc Method {0} has been patched to attempt networking but lacks any RpcAttributes! This should never happen!";

		private const string MethodPatchedAndNetworkCalledButLacksAttributesConst = "Rpc Method {0} has been patched && even received a network call to execute but lacks any RpcAttributes! This should never happen! Something is VERY fucky!!!";

		private const string RpcCalledBeforeObjectSpawnedConst = "An RPC called on a NetworkObject that is not in the spawned objects list. Please make sure the NetworkObject is spawned before calling RPCs.";

		private const string NetworkCalledNonExistentMethodConst = "NetworkBehaviour {0} received RPC {1} but that method doesn't exist on {2}!";

		private const string ObjectNotSerializableConst = "[Network] Parameter ({0} {1}) is not marked [Serializable] nor does it implement INetworkSerializable!";

		private const string InconsistentParameterCountConst = "[Network] NetworkBehaviour received a RPC {0} but the number of parameters sent {1} != MethodInfo param count {2}";

		private const string PluginTriedToBindToPreExistingObjectTooLateConst = "Plugin '{0}' tried to bind {1} to {2} but it's too late! Make sure you bind to any pre-existing NetworkObjects before NetworkManager.IsListening || IsConnectedClient.";

		private const string RegisteredPatchForTypeConst = "Successfully registered first patch for type {0}.{1} | Triggered by {2}";

		private const string CustomComponentAddedToExistingObjectConst = "Successfully added {0} to {1} via {2}. Triggered by plugin {3}";

		private const string PluginUnpatchedAllRPCsConst = "Plugin {0} has unpatched all RPCs!";

		internal static string NoNetworkManagerPresentToSendRpc(NetworkBehaviour networkBehaviour)
		{
			return $"NetworkBehaviour {networkBehaviour.NetworkBehaviourId} tried to send a RPC but the NetworkManager is non-existant!";
		}

		internal static string MethodLacksRpcAttribute(MethodInfo method)
		{
			return string.Format("Can't patch method {0}.{1} because it lacks a [{2}] attribute.", method.DeclaringType?.Name, method.Name, method.Name.EndsWith("ServerRpc") ? "ServerRpc" : "ClientRpc");
		}

		internal static string MethodLacksSuffix(MethodBase method)
		{
			return string.Format("Can't patch method {0}.{1} because it's name doesn't end with '{2}'!", method.DeclaringType?.Name, method.Name, (((MemberInfo)method).GetCustomAttribute<ServerRpcAttribute>() != null) ? "ServerRpc" : "ClientRpc");
		}

		internal static string SuccessfullyPatchedType(Type networkType, int serverRpcCount, int clientRpcCount)
		{
			return string.Format("Patched {0} ServerRPC{1} & {2} ClientRPC{3} on NetworkBehaviour {4}.", serverRpcCount, (serverRpcCount == 1) ? "" : "s", clientRpcCount, (clientRpcCount == 1) ? "" : "s", networkType.Name);
		}

		internal static string NotOwnerOfNetworkObject(string whoIsNotOwner, MethodBase method, NetworkObject networkObject)
		{
			return $"{whoIsNotOwner} tried to run ServerRPC {method.Name} but not the owner of NetworkObject {networkObject.NetworkObjectId}";
		}

		internal static string CantRunClientRpcFromClient(MethodBase method)
		{
			return $"Tried to run ClientRpc {method.Name} but we're not a host! You should only call ClientRpc(s) from inside a ServerRpc OR if you've checked you're on the server with IsHost!";
		}

		internal static string CantRunServerRpcAsClient(MethodBase method)
		{
			return $"Received message to run ServerRPC {method.DeclaringType?.Name}.{method.Name} but we're a client!";
		}

		internal static string MethodPatchedButLacksAttributes(MethodBase method)
		{
			return $"Rpc Method {method.Name} has been patched to attempt networking but lacks any RpcAttributes! This should never happen!";
		}

		internal static string MethodPatchedAndNetworkCalledButLacksAttributes(MethodBase method)
		{
			return $"Rpc Method {method.Name} has been patched && even received a network call to execute but lacks any RpcAttributes! This should never happen! Something is VERY fucky!!!";
		}

		internal static string RpcCalledBeforeObjectSpawned()
		{
			return "An RPC called on a NetworkObject that is not in the spawned objects list. Please make sure the NetworkObject is spawned before calling RPCs.";
		}

		internal static string NetworkCalledNonExistentMethod(NetworkBehaviour networkBehaviour, string rpcName)
		{
			return $"NetworkBehaviour {networkBehaviour.NetworkBehaviourId} received RPC {rpcName} but that method doesn't exist on {((object)networkBehaviour).GetType().Name}!";
		}

		internal static string ObjectNotSerializable(ParameterInfo paramInfo)
		{
			return $"[Network] Parameter ({paramInfo.ParameterType.Name} {paramInfo.Name}) is not marked [Serializable] nor does it implement INetworkSerializable!";
		}

		internal static string InconsistentParameterCount(MethodBase method, int paramsSent)
		{
			return $"[Network] NetworkBehaviour received a RPC {method.Name} but the number of parameters sent {paramsSent} != MethodInfo param count {method.GetParameters().Length}";
		}

		internal static string PluginTriedToBindToPreExistingObjectTooLate(NetcodeValidator netcodeValidator, Type from, Type to)
		{
			return $"Plugin '{netcodeValidator.PluginGuid}' tried to bind {from.Name} to {to.Name} but it's too late! Make sure you bind to any pre-existing NetworkObjects before NetworkManager.IsListening || IsConnectedClient.";
		}

		internal static string RegisteredPatchForType(NetcodeValidator validator, Type netBehaviour, MethodBase method)
		{
			return $"Successfully registered first patch for type {netBehaviour.Name}.{method.Name} | Triggered by {validator.PluginGuid}";
		}

		internal static string CustomComponentAddedToExistingObject((NetcodeValidator validator, Type custom, Type native) it, MethodBase methodBase)
		{
			return $"Successfully added {it.custom.Name} to {it.native.Name} via {methodBase.Name}. Triggered by plugin {it.validator.PluginGuid}";
		}

		internal static string PluginUnpatchedAllRPCs(NetcodeValidator netcodeValidator)
		{
			return $"Plugin {netcodeValidator.PluginGuid} has unpatched all RPCs!";
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "NicholaScott.BepInEx.RuntimeNetcodeRPCValidator";

		public const string PLUGIN_NAME = "RuntimeNetcodeRPCValidator";

		public const string PLUGIN_VERSION = "0.2.5";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

mods/Sligili-HDLethalCompany-1.5.6/BepInEx/plugins/HDLethalCompany.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HDLethalCompany.Patch;
using HDLethalCompany.Tools;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("HDLethalCompanyRemake")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HDLethalCompanyRemake")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7f379bc1-1fd4-4c72-9247-a181862eec6b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HDLethalCompany
{
	[BepInPlugin("HDLethalCompany", "HDLethalCompany-Sligili", "1.5.6")]
	public class HDLethalCompanyInitialization : BaseUnityPlugin
	{
		private static ConfigEntry<float> config_ResMult;

		private static ConfigEntry<bool> config_EnablePostProcessing;

		private static ConfigEntry<bool> config_EnableFog;

		private static ConfigEntry<bool> config_EnableAntialiasing;

		private static ConfigEntry<bool> config_EnableResolution;

		private static ConfigEntry<bool> config_EnableFoliage;

		private static ConfigEntry<int> config_FogQuality;

		private static ConfigEntry<int> config_TextureQuality;

		private static ConfigEntry<int> config_LOD;

		private static ConfigEntry<int> config_ShadowmapQuality;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HDLethalCompany loaded");
			ConfigFile();
			GraphicsPatch.assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "HDLethalCompany/hdlethalcompany"));
			_harmony = new Harmony("HDLethalCompany");
			_harmony.PatchAll(typeof(GraphicsPatch));
		}

		private void ConfigFile()
		{
			config_ResMult = ((BaseUnityPlugin)this).Config.Bind<float>("RESOLUTION", "Value", 2.233f, "Resolution Scale Multiplier - <EXAMPLES -> | 1.000 = 860x520p | 2.233 =~ 1920x1080p | 2.977 = 2560x1440p | 4.465 = 3840x2060p > - The UI scanned elements have slightly incorrect offsets after 3.000");
			config_EnableResolution = ((BaseUnityPlugin)this).Config.Bind<bool>("RESOLUTION", "EnableRes", true, "Resolution Fix - In case you wanna use another resolution mod or apply any widescreen mod while keeping the graphics settings");
			config_EnableAntialiasing = ((BaseUnityPlugin)this).Config.Bind<bool>("EFFECTS", "EnableAA", false, "Anti-Aliasing (Unity's SMAA)");
			config_EnablePostProcessing = ((BaseUnityPlugin)this).Config.Bind<bool>("EFFECTS", "EnablePP", true, "Post-Processing (Color grading)");
			config_TextureQuality = ((BaseUnityPlugin)this).Config.Bind<int>("EFFECTS", "TextureQuality", 3, "Texture Resolution Quality - <PRESETS -> | 0 = VERY LOW (1/8) | 1 = LOW (1/4) | 2 = MEDIUM (1/2) | 3 = HIGH (1/1 VANILLA) >");
			config_FogQuality = ((BaseUnityPlugin)this).Config.Bind<int>("EFFECTS", "FogQuality", 1, "Volumetric Fog Quality - <PRESETS -> | 0 = VERY LOW | 1 = VANILLA FOG | 2 = MEDIUM | 3 = HIGH >");
			config_EnableFog = ((BaseUnityPlugin)this).Config.Bind<bool>("EFFECTS", "EnableFOG", true, "Volumetric Fog Toggle - Use this as a last resource in case lowering the fog quality is not enough to get decent performance");
			config_LOD = ((BaseUnityPlugin)this).Config.Bind<int>("EFFECTS", "LOD", 1, "Level Of Detail - <PRESETS -> | 0 = LOW (HALF DISTANCE) | 1 = VANILLA | 2 = HIGH (TWICE THE DISTANCE) >");
			config_ShadowmapQuality = ((BaseUnityPlugin)this).Config.Bind<int>("EFFECTS", "ShadowQuality", 3, "Shadows Resolution - <PRESETS -> 0 = VERY LOW (SHADOWS DISABLED)| 1 = LOW (256) | 2 = MEDIUM (1024) | 3 = VANILLA (2048) > - Shadowmap max resolution");
			config_EnableFoliage = ((BaseUnityPlugin)this).Config.Bind<bool>("EFFECTS", "EnableF", true, "Foliage Toggle - If the game camera should or not render bushes/grass (trees won't be affected)");
			GraphicsPatch.m_enableFoliage = config_EnableFoliage.Value;
			GraphicsPatch.m_enableResolutionFix = config_EnableResolution.Value;
			GraphicsPatch.m_setShadowQuality = config_ShadowmapQuality.Value;
			GraphicsPatch.m_setLOD = config_LOD.Value;
			GraphicsPatch.m_setTextureResolution = config_TextureQuality.Value;
			GraphicsPatch.m_setFogQuality = config_FogQuality.Value;
			GraphicsPatch.multiplier = config_ResMult.Value;
			GraphicsPatch.anchorOffsetZ = 0.123f * config_ResMult.Value + 0.877f;
			GraphicsPatch.m_widthResolution = 860f * config_ResMult.Value;
			GraphicsPatch.m_heightResolution = 520f * config_ResMult.Value;
			GraphicsPatch.m_enableAntiAliasing = config_EnableAntialiasing.Value;
			GraphicsPatch.m_enableFog = config_EnableFog.Value;
			GraphicsPatch.m_enablePostProcessing = config_EnablePostProcessing.Value;
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "HDLethalCompany";

		public const string Name = "HDLethalCompany-Sligili";

		public const string Ver = "1.5.6";
	}
}
namespace HDLethalCompany.Tools
{
	public class Reflection
	{
		public static object GetInstanceField(Type type, object instance, string fieldName)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(fieldName, bindingAttr);
			return field.GetValue(instance);
		}

		public static object CallMethod(object instance, string methodName, params object[] args)
		{
			MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				return method.Invoke(instance, args);
			}
			return null;
		}
	}
}
namespace HDLethalCompany.Patch
{
	internal class GraphicsPatch
	{
		public static bool m_enablePostProcessing;

		public static bool m_enableFog;

		public static bool m_enableAntiAliasing;

		public static bool m_enableResolutionFix;

		public static bool m_enableFoliage = true;

		public static int m_setFogQuality;

		public static int m_setTextureResolution;

		public static int m_setLOD;

		public static int m_setShadowQuality;

		private static HDRenderPipelineAsset myAsset;

		public static AssetBundle assetBundle;

		public static float anchorOffsetX = 439.48f;

		public static float anchorOffsetY = 244.8f;

		public static float anchorOffsetZ;

		public static float multiplier;

		public static float m_widthResolution;

		public static float m_heightResolution;

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPrefix]
		private static void StartPrefix(PlayerControllerB __instance)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(HDAdditionalCameraData));
			foreach (Object obj in array)
			{
				HDAdditionalCameraData val = (HDAdditionalCameraData)(object)((obj is HDAdditionalCameraData) ? obj : null);
				if (!(((Object)((Component)val).gameObject).name == "MapCamera"))
				{
					val.customRenderingSettings = true;
					ToggleCustomPass(val, m_enablePostProcessing);
					SetLevelOfDetail(val);
					ToggleVolumetricFog(val, m_enableFog);
					if (!m_enableFoliage)
					{
						LayerMask val2 = LayerMask.op_Implicit(((Component)val).GetComponent<Camera>().cullingMask);
						val2 = LayerMask.op_Implicit(LayerMask.op_Implicit(val2) & -1025);
						((Component)val).GetComponent<Camera>().cullingMask = LayerMask.op_Implicit(val2);
					}
					SetShadowQuality(assetBundle, val);
					if (!(((Object)((Component)val).gameObject).name == "SecurityCamera") && !(((Object)((Component)val).gameObject).name == "ShipCamera"))
					{
						SetAntiAliasing(val);
					}
				}
			}
			array = null;
			SetTextureQuality();
			SetFogQuality();
			if (m_enableResolutionFix && multiplier != 1f)
			{
				int width = (int)Math.Round(m_widthResolution, 0);
				int height = (int)Math.Round(m_heightResolution, 0);
				((Texture)__instance.gameplayCamera.targetTexture).width = width;
				((Texture)__instance.gameplayCamera.targetTexture).height = height;
			}
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
		[HarmonyPrefix]
		private static void RoundPostFix()
		{
			SetFogQuality();
			if (m_setLOD == 0)
			{
				RemoveLodFromGameObject("CatwalkStairs");
			}
		}

		[HarmonyPatch(typeof(HUDManager), "UpdateScanNodes")]
		[HarmonyPostfix]
		private static void UpdateScanNodesPostfix(PlayerControllerB playerScript, HUDManager __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			if (anchorOffsetZ > 1.238f)
			{
				anchorOffsetZ = 1.238f;
			}
			if (!m_enableResolutionFix || multiplier == 1f)
			{
				return;
			}
			Vector3 zero = Vector3.zero;
			bool flag = false;
			for (int i = 0; i < __instance.scanElements.Length; i++)
			{
				if ((Traverse.Create((object)__instance).Field("scanNodes").GetValue() as Dictionary<RectTransform, ScanNodeProperties>).Count > 0 && (Traverse.Create((object)__instance).Field("scanNodes").GetValue() as Dictionary<RectTransform, ScanNodeProperties>).TryGetValue(__instance.scanElements[i], out var value) && (Object)(object)value != (Object)null)
				{
					try
					{
						if ((bool)Reflection.CallMethod(__instance, "NodeIsNotVisible", value, i))
						{
							continue;
						}
						if (!((Component)__instance.scanElements[i]).gameObject.activeSelf)
						{
							((Component)__instance.scanElements[i]).gameObject.SetActive(true);
							((Component)__instance.scanElements[i]).GetComponent<Animator>().SetInteger("colorNumber", value.nodeType);
							if (value.creatureScanID != -1)
							{
								Traverse.Create((object)__instance).Method("AttemptScanNewCreature", new object[1] { value.creatureScanID });
							}
						}
						goto IL_0186;
					}
					catch (Exception arg)
					{
						Debug.LogError((object)$"Error in updatescanNodes A: {arg}");
						goto IL_0186;
					}
				}
				(Traverse.Create((object)__instance).Field("scanNodes").GetValue() as Dictionary<RectTransform, ScanNodeProperties>).Remove(__instance.scanElements[i]);
				((Component)__instance.scanElements[i]).gameObject.SetActive(false);
				continue;
				IL_0186:
				try
				{
					Traverse.Create((object)__instance).Field("scanElementText").SetValue((object)((Component)__instance.scanElements[i]).gameObject.GetComponentsInChildren<TextMeshProUGUI>());
					if ((Traverse.Create((object)__instance).Field("scanElementText").GetValue() as TextMeshProUGUI[]).Length > 1)
					{
						((TMP_Text)(Traverse.Create((object)__instance).Field("scanElementText").GetValue() as TextMeshProUGUI[])[0]).text = value.headerText;
						((TMP_Text)(Traverse.Create((object)__instance).Field("scanElementText").GetValue() as TextMeshProUGUI[])[1]).text = value.subText;
					}
					if (value.nodeType == 2)
					{
						flag = true;
					}
					zero = playerScript.gameplayCamera.WorldToScreenPoint(((Component)value).transform.position);
					((Transform)__instance.scanElements[i]).position = new Vector3(((Transform)__instance.scanElements[i]).position.x, ((Transform)__instance.scanElements[i]).position.y, 12.17f * anchorOffsetZ);
					__instance.scanElements[i].anchoredPosition = Vector2.op_Implicit(new Vector3(zero.x - anchorOffsetX * multiplier, zero.y - anchorOffsetY * multiplier));
					if (!(multiplier > 3f))
					{
						((Transform)__instance.scanElements[i]).localScale = new Vector3(multiplier, multiplier, multiplier);
					}
					else
					{
						((Transform)__instance.scanElements[i]).localScale = new Vector3(3f, 3f, 3f);
					}
				}
				catch (Exception arg2)
				{
					Debug.LogError((object)$"Error in updatescannodes B: {arg2}");
				}
			}
			try
			{
				if (!flag)
				{
					__instance.totalScrapScanned = 0;
					Traverse.Create((object)__instance).Field("totalScrapScannedDisplayNum").SetValue((object)0);
					Traverse.Create((object)__instance).Field("addToDisplayTotalInterval").SetValue((object)0.35f);
				}
				__instance.scanInfoAnimator.SetBool("display", (int)Reflection.GetInstanceField(typeof(HUDManager), __instance, "scannedScrapNum") >= 2 && flag);
			}
			catch (Exception arg3)
			{
				Debug.LogError((object)$"Error in updatescannodes C: {arg3}");
			}
		}

		public static void SetShadowQuality(AssetBundle assetBundle, HDAdditionalCameraData cameraData)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)assetBundle == (Object)null)
			{
				Debug.LogError((object)"HDLETHALCOMPANY: Something is wrong with the Asset Bundle - Null");
				return;
			}
			((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[20u] = true;
			((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)20, (m_setShadowQuality != 0) ? true : false);
			myAsset = (HDRenderPipelineAsset)((m_setShadowQuality != 1) ? ((m_setShadowQuality != 2) ? ((object)(HDRenderPipelineAsset)QualitySettings.renderPipeline) : ((object)(myAsset = assetBundle.LoadAsset<HDRenderPipelineAsset>("Assets/HDLethalCompany/MediumShadowsAsset.asset")))) : (myAsset = assetBundle.LoadAsset<HDRenderPipelineAsset>("Assets/HDLethalCompany/VeryLowShadowsAsset.asset")));
			QualitySettings.renderPipeline = (RenderPipelineAsset)(object)myAsset;
		}

		public static void SetLevelOfDetail(HDAdditionalCameraData cameraData)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (m_setLOD != 1)
			{
				((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[60u] = true;
				((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[61u] = true;
				((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)60, true);
				((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)61, true);
				cameraData.renderingPathCustomFrameSettings.lodBiasMode = (LODBiasMode)2;
				cameraData.renderingPathCustomFrameSettings.lodBias = ((m_setLOD == 0) ? 0.6f : 2.3f);
				if (m_setLOD == 0 && ((Component)cameraData).GetComponent<Camera>().farClipPlane > 180f)
				{
					((Component)cameraData).GetComponent<Camera>().farClipPlane = 170f;
				}
			}
		}

		public static void SetTextureQuality()
		{
			if (m_setTextureResolution < 3)
			{
				int globalTextureMipmapLimit = 3 - m_setTextureResolution;
				QualitySettings.globalTextureMipmapLimit = globalTextureMipmapLimit;
			}
		}

		public static void SetAntiAliasing(HDAdditionalCameraData cameraData)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (m_enableAntiAliasing)
			{
				cameraData.antialiasing = (AntialiasingMode)3;
			}
		}

		public static void ToggleCustomPass(HDAdditionalCameraData cameraData, bool enable)
		{
			((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[6u] = true;
			((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)6, enable);
		}

		public static void ToggleVolumetricFog(HDAdditionalCameraData cameraData, bool enable)
		{
			((BitArray128)(ref cameraData.renderingPathCustomFrameSettingsOverrideMask.mask))[28u] = true;
			((FrameSettings)(ref cameraData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, enable);
		}

		public static void SetFogQuality()
		{
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(Volume));
			if (array.Length == 0)
			{
				Debug.LogError((object)"No volumes found");
				return;
			}
			Fog val2 = default(Fog);
			foreach (Object obj in array)
			{
				Volume val = (Volume)(object)((obj is Volume) ? obj : null);
				if (val.sharedProfile.TryGet<Fog>(ref val2))
				{
					((VolumeParameter<int>)(object)((VolumeComponentWithQuality)val2).quality).Override(3);
					switch (m_setFogQuality)
					{
					case -1:
						val2.volumetricFogBudget = 0.05f;
						val2.resolutionDepthRatio = 0.5f;
						break;
					case 0:
						val2.volumetricFogBudget = 0.05f;
						val2.resolutionDepthRatio = 0.5f;
						break;
					case 2:
						val2.volumetricFogBudget = 0.333f;
						val2.resolutionDepthRatio = 0.666f;
						break;
					case 3:
						val2.volumetricFogBudget = 0.666f;
						val2.resolutionDepthRatio = 0.5f;
						break;
					}
				}
			}
		}

		public static void RemoveLodFromGameObject(string name)
		{
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(LODGroup));
			foreach (Object obj in array)
			{
				LODGroup val = (LODGroup)(object)((obj is LODGroup) ? obj : null);
				if (((Object)((Component)val).gameObject).name == name)
				{
					val.enabled = false;
				}
			}
		}
	}
}

mods/Sligili-More_Emotes-1.3.3/BepInEx/plugins/MoreEmotes1.3.3.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using MoreEmotes.Patch;
using MoreEmotes.Scripts;
using RuntimeNetcodeRPCValidator;
using TMPro;
using Tools;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FuckYouMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FuckYouMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5ecc2bf2-af12-4e83-a6f1-cf2eacbf3060")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tools
{
	public class Ref
	{
		public static object GetInstanceField(Type type, object instance, string fieldName)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(fieldName, bindingAttr);
			return field.GetValue(instance);
		}

		public static object Method(object instance, string methodName, params object[] args)
		{
			MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				return method.Invoke(instance, args);
			}
			return null;
		}
	}
	public class D : MonoBehaviour
	{
		public static bool Debug;

		public static void L(string msg)
		{
			if (Debug)
			{
				Debug.Log((object)msg);
			}
		}

		public static void W(string msg)
		{
			if (Debug)
			{
				Debug.LogWarning((object)msg);
			}
		}
	}
}
namespace MoreEmotes
{
	[BepInPlugin("MoreEmotes", "MoreEmotes-Sligili", "1.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MoreEmotesInitialization : BaseUnityPlugin
	{
		private Harmony _harmony;

		private NetcodeValidator netcodeValidator;

		private ConfigEntry<string> config_KeyWheel;

		private ConfigEntry<string> config_KeyWheel_c;

		private ConfigEntry<bool> config_InventoryCheck;

		private ConfigEntry<bool> config_UseConfigFile;

		private ConfigEntry<string> config_KeyEmote3;

		private ConfigEntry<string> config_KeyEmote4;

		private ConfigEntry<string> config_KeyEmote5;

		private ConfigEntry<string> config_KeyEmote6;

		private ConfigEntry<string> config_KeyEmote7;

		private ConfigEntry<string> config_KeyEmote8;

		private ConfigEntry<string> config_KeyEmote9;

		private ConfigEntry<string> config_KeyEmote10;

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreEmotes loaded");
			LoadAssetBundles();
			LoadAssets();
			ConfigFile();
			SearchForIncompatibleMods();
			_harmony = new Harmony("MoreEmotes");
			_harmony.PatchAll(typeof(EmotePatch));
			netcodeValidator = new NetcodeValidator("MoreEmotes");
			netcodeValidator.PatchAll();
			netcodeValidator.BindToPreExistingObjectByBehaviour<SignEmoteText, PlayerControllerB>();
			netcodeValidator.BindToPreExistingObjectByBehaviour<SyncAnimatorToOthers, PlayerControllerB>();
		}

		private void LoadAssetBundles()
		{
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animationsbundle");
			string text2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animatorbundle");
			try
			{
				EmotePatch.AnimationsBundle = AssetBundle.LoadFromFile(text);
				EmotePatch.AnimatorBundle = AssetBundle.LoadFromFile(text2);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load AssetBundles. Make sure \"animatorsbundle\" and \"animationsbundle\" are inside the MoreEmotes folder.\nError: " + ex.Message));
			}
		}

		private void LoadAssets()
		{
			string path = "Assets/MoreEmotes";
			EmotePatch.local = EmotePatch.AnimatorBundle.LoadAsset<RuntimeAnimatorController>(Path.Combine(path, "NEWmetarig.controller"));
			EmotePatch.others = EmotePatch.AnimatorBundle.LoadAsset<RuntimeAnimatorController>(Path.Combine(path, "NEWmetarigOtherPlayers.controller"));
			MoreEmotesEvents.ClapSounds[0] = EmotePatch.AnimationsBundle.LoadAsset<AudioClip>(Path.Combine(path, "SingleClapEmote1.wav"));
			MoreEmotesEvents.ClapSounds[1] = EmotePatch.AnimationsBundle.LoadAsset<AudioClip>(Path.Combine(path, "SingleClapEmote2.wav"));
			EmotePatch.SettingsPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>(Path.Combine(path, "Resources/MoreEmotesPanel.prefab"));
			EmotePatch.ButtonPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>(Path.Combine(path, "Resources/MoreEmotesButton.prefab"));
			EmotePatch.LegsPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>(Path.Combine(path, "Resources/plegs.prefab"));
			EmotePatch.SignPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>(Path.Combine(path, "Resources/Sign.prefab"));
			EmotePatch.SignUIPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>(Path.Combine(path, "Resources/SignTextUI.prefab"));
			EmotePatch.WheelPrefab = EmotePatch.AnimationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesMenu.prefab");
		}

		private void ConfigFile()
		{
			EmotePatch.ConfigFile_Keybinds = new string[32];
			config_KeyWheel = ((BaseUnityPlugin)this).Config.Bind<string>("EMOTE WHEEL", "Key", "v", (ConfigDescription)null);
			EmotePatch.ConfigFile_WheelKeybind = config_KeyWheel.Value;
			config_KeyWheel_c = ((BaseUnityPlugin)this).Config.Bind<string>("EMOTE WHEEL (Controller)", "Key", "leftshoulder", (ConfigDescription)null);
			EmotePatch.ConfigFile_WheelKeybind_controller = config_KeyWheel_c.Value;
			config_InventoryCheck = ((BaseUnityPlugin)this).Config.Bind<bool>("OTHERS", "InventoryCheck", true, "Prevents some emotes from performing while holding any item/scrap");
			EmotePatch.ConfigFile_InventoryCheck = config_InventoryCheck.Value;
			config_UseConfigFile = ((BaseUnityPlugin)this).Config.Bind<bool>("OTHERS", "ConfigFile", false, "Ignores all in-game saved settings and instead uses the config file");
			EmotePatch.UseConfigFile = config_UseConfigFile.Value;
			config_KeyEmote3 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Middle Finger", "3", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[2] = config_KeyEmote3.Value.Replace(" ", "");
			config_KeyEmote4 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "The Griddy", "6", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[5] = config_KeyEmote4.Value.Replace(" ", "");
			config_KeyEmote5 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Shy", "5", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[4] = config_KeyEmote5.Value.Replace(" ", "");
			config_KeyEmote6 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Clap", "4", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[3] = config_KeyEmote6.Value.Replace(" ", "");
			config_KeyEmote7 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Twerk", "7", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[6] = config_KeyEmote7.Value.Replace(" ", "");
			config_KeyEmote8 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Salute", "8", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[7] = config_KeyEmote8.Value.Replace(" ", "");
			config_KeyEmote9 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Prisyadka", "9", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[8] = config_KeyEmote9.Value.Replace(" ", "");
			config_KeyEmote10 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Sign", "0", (ConfigDescription)null);
			EmotePatch.ConfigFile_Keybinds[9] = config_KeyEmote10.Value.Replace(" ", "");
		}

		private void SearchForIncompatibleMods()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				BepInPlugin metadata = pluginInfo.Value.Metadata;
				if (metadata.GUID.Equals("com.malco.lethalcompany.moreshipupgrades", StringComparison.OrdinalIgnoreCase) || metadata.GUID.Equals("Stoneman.LethalProgression", StringComparison.OrdinalIgnoreCase))
				{
					EmotePatch.IncompatibleStuff = true;
					break;
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "MoreEmotes";

		public const string NAME = "MoreEmotes-Sligili";

		public const string VER = "1.3.3";
	}
}
namespace MoreEmotes.Patch
{
	public enum Emotes
	{
		D_Sign = 1010,
		D_Clap = 1004,
		D_Middle_Finger = 1003,
		Dance = 1,
		Point = 2,
		Middle_Finger = 3,
		Clap = 4,
		Shy = 5,
		The_Griddy = 6,
		Twerk = 7,
		Salute = 8,
		Prisyadka = 9,
		Sign = 10
	}
	public class EmotePatch
	{
		public static AssetBundle AnimationsBundle;

		public static AssetBundle AnimatorBundle;

		public static RuntimeAnimatorController local;

		public static RuntimeAnimatorController others;

		public static bool UseConfigFile;

		public static string[] ConfigFile_Keybinds;

		public static string ConfigFile_WheelKeybind;

		public static string ConfigFile_WheelKeybind_controller;

		public static bool ConfigFile_InventoryCheck;

		public static string EmoteWheelKeyboard;

		public static string EmoteWheelController;

		public static bool IncompatibleStuff;

		private static int s_currentEmoteID = 0;

		private static float s_defaultPlayerSpeed;

		private static bool[] s_wasPerformingEmote = new bool[32];

		public static bool IsEmoteWheelOpen;

		private static bool s_isPlayerFirstFrame;

		private static bool s_isFirstTimeOnMenu;

		private static bool s_isPlayerSpawning;

		public const int AlternateEmoteIDOffset = 1000;

		private static int[] s_doubleEmotesIDS = new int[2] { 3, 4 };

		public static bool LocalArmsSeparatedFromCamera;

		private static Transform s_freeArmsTarget;

		private static Transform s_lockedArmsTarget;

		private static CallbackContext emptyContext;

		public static GameObject ButtonPrefab;

		public static GameObject SettingsPrefab;

		public static GameObject LegsPrefab;

		public static GameObject SignPrefab;

		public static GameObject SignUIPrefab;

		public static GameObject WheelPrefab;

		private static GameObject s_localPlayerLevelBadge;

		private static GameObject s_localPlayerBetaBadge;

		private static Transform s_legsMesh;

		private static EmoteWheel s_selectionWheel;

		private static SignUI s_customSignInputField;

		private static SyncAnimatorToOthers s_syncAnimator;

		private static int _AlternateEmoteIDOffset => 1000;

		private static void InstantiateSettingsMenu(Transform container)
		{
			RebindButton.ConfigFile_Keybinds = ConfigFile_Keybinds;
			if (!PlayerPrefs.HasKey("InvCheck") || UseConfigFile)
			{
				PlayerPrefs.SetInt("InvCheck", ConfigFile_InventoryCheck ? 1 : 0);
			}
			ToggleButton.s_InventoryCheck = (UseConfigFile ? ConfigFile_InventoryCheck : (PlayerPrefs.GetInt("InvCheck") == 1));
			SetupUI.UseConfigFile = UseConfigFile;
			SetupUI.InventoryCheck = ToggleButton.s_InventoryCheck;
			GameObject gameObject = ((Component)((Component)container).transform.Find("SettingsPanel")).gameObject;
			Object.Instantiate<GameObject>(ButtonPrefab, gameObject.transform).transform.SetSiblingIndex(7);
			Object.Instantiate<GameObject>(SettingsPrefab, gameObject.transform);
			gameObject.AddComponent<SetupUI>();
		}

		private static void CheckEmoteInput(string keyBind, bool needsEmptyHands, int emoteID, PlayerControllerB player)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			Emotes emotes = (Emotes)emoteID;
			string text = emotes.ToString();
			bool flag;
			if (UseConfigFile)
			{
				flag = ConfigFile_InventoryCheck;
				keyBind = ConfigFile_Keybinds[emoteID - 1];
			}
			else
			{
				flag = PlayerPrefs.GetInt("InvCheck") == 1;
				if (PlayerPrefs.HasKey(text))
				{
					keyBind = PlayerPrefs.GetString(text);
				}
				else
				{
					PlayerPrefs.SetString(text, keyBind);
				}
			}
			if (!keyBind.Equals(string.Empty) && InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind], 0f) && (!player.isHoldingObject || !needsEmptyHands || !flag))
			{
				player.PerformEmote(emptyContext, emoteID);
			}
		}

		private static void CheckWheelInput(string keybind, string controller, PlayerControllerB player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			bool flag2 = false;
			if (Gamepad.all.Count != 0 && !controller.Equals(string.Empty))
			{
				flag = InputControlExtensions.IsPressed(((InputControl)Gamepad.current)[controller], 0f);
			}
			if (keybind != string.Empty)
			{
				flag2 = InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keybind], 0f) && !((ButtonControl)Keyboard.current[(Key)55]).wasPressedThisFrame;
			}
			bool flag3 = flag || flag2;
			if (flag3 && !IsEmoteWheelOpen && !player.isPlayerDead && !player.inTerminalMenu && !player.quickMenuManager.isMenuOpen && !player.isTypingChat && !s_customSignInputField.IsSignUIOpen)
			{
				IsEmoteWheelOpen = true;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)2;
				((Component)s_selectionWheel).gameObject.SetActive(IsEmoteWheelOpen);
				player.disableLookInput = true;
			}
			else
			{
				if (!IsEmoteWheelOpen || (flag3 && !player.quickMenuManager.isMenuOpen && !player.isTypingChat && !s_customSignInputField.IsSignUIOpen))
				{
					return;
				}
				int selectedEmoteID = s_selectionWheel.SelectedEmoteID;
				if (!player.quickMenuManager.isMenuOpen && !s_customSignInputField.IsSignUIOpen)
				{
					Cursor.visible = false;
					Cursor.lockState = (CursorLockMode)1;
				}
				if (!player.isPlayerDead && !player.quickMenuManager.isMenuOpen)
				{
					if (selectedEmoteID <= 3 || selectedEmoteID == 6 || !ConfigFile_InventoryCheck)
					{
						player.PerformEmote(emptyContext, selectedEmoteID);
					}
					else if (!player.isHoldingObject)
					{
						player.PerformEmote(emptyContext, selectedEmoteID);
					}
				}
				if (!s_customSignInputField.IsSignUIOpen)
				{
					player.disableLookInput = false;
				}
				IsEmoteWheelOpen = false;
				((Component)s_selectionWheel).gameObject.SetActive(IsEmoteWheelOpen);
			}
		}

		private static void OnFirstLocalPlayerFrameWithNewAnimator(PlayerControllerB player)
		{
			s_isPlayerFirstFrame = false;
			TurnControllerIntoAnOverrideController(player.playerBodyAnimator.runtimeAnimatorController);
			s_syncAnimator = ((Component)player).GetComponent<SyncAnimatorToOthers>();
			s_customSignInputField.Player = player;
			s_freeArmsTarget = Object.Instantiate<Transform>(player.localArmsRotationTarget, player.localArmsRotationTarget.parent.parent);
			s_lockedArmsTarget = player.localArmsRotationTarget;
			Transform val = ((Component)player).transform.Find("ScavengerModel").Find("metarig").Find("spine")
				.Find("spine.001")
				.Find("spine.002")
				.Find("spine.003");
			s_localPlayerLevelBadge = ((Component)val.Find("LevelSticker")).gameObject;
			s_localPlayerBetaBadge = ((Component)val.Find("BetaBadge")).gameObject;
			player.SpawnPlayerAnimation();
		}

		private static void SpawnSign(PlayerControllerB player)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(SignPrefab, ((Component)((Component)((Component)player).transform.Find("ScavengerModel")).transform.Find("metarig")).transform);
			val.transform.SetSiblingIndex(6);
			((Object)val).name = "Sign";
			val.transform.localPosition = new Vector3(0.029f, -0.45f, 1.3217f);
			val.transform.localRotation = Quaternion.Euler(65.556f, 180f, 180f);
		}

		private static void SpawnLegs(PlayerControllerB player)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(LegsPrefab, ((Component)((Component)player.playerBodyAnimator).transform.parent).transform);
			s_legsMesh = val.transform.Find("Mesh");
			((Component)s_legsMesh).transform.parent = ((Component)player.playerBodyAnimator).transform.parent;
			((Object)s_legsMesh).name = "LEGS";
			GameObject gameObject = ((Component)val.transform.Find("Armature")).gameObject;
			gameObject.transform.parent = ((Component)player.playerBodyAnimator).transform;
			((Object)gameObject).name = "FistPersonLegs";
			gameObject.transform.position = new Vector3(0f, 0.197f, 0f);
			gameObject.transform.localScale = new Vector3(13.99568f, 13.99568f, 13.99568f);
			Object.Destroy((Object)(object)val);
		}

		private static void ResetIKWeights(PlayerControllerB player)
		{
			Transform val = ((Component)player.playerBodyAnimator).transform.Find("Rig 1");
			ChainIKConstraint component = ((Component)val.Find("RightArm")).GetComponent<ChainIKConstraint>();
			ChainIKConstraint component2 = ((Component)val.Find("LeftArm")).GetComponent<ChainIKConstraint>();
			TwoBoneIKConstraint component3 = ((Component)val.Find("RightLeg")).GetComponent<TwoBoneIKConstraint>();
			TwoBoneIKConstraint component4 = ((Component)val.Find("LeftLeg")).GetComponent<TwoBoneIKConstraint>();
			Transform val2 = ((Component)player.playerBodyAnimator).transform.Find("ScavengerModelArmsOnly").Find("metarig").Find("spine.003")
				.Find("RigArms");
			ChainIKConstraint component5 = ((Component)val2.Find("RightArm")).GetComponent<ChainIKConstraint>();
			ChainIKConstraint component6 = ((Component)val2.Find("LeftArm")).GetComponent<ChainIKConstraint>();
			((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)component).weight = 1f;
			((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)component2).weight = 1f;
			((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)component).weight = 1f;
			((RigConstraint<TwoBoneIKConstraintJob, TwoBoneIKConstraintData, TwoBoneIKConstraintJobBinder<TwoBoneIKConstraintData>>)(object)component4).weight = 1f;
			((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)component5).weight = 1f;
			((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)component6).weight = 1f;
		}

		private static void UpdateLegsMaterial(PlayerControllerB player)
		{
			((Renderer)((Component)s_legsMesh).GetComponent<SkinnedMeshRenderer>()).material = ((Renderer)((Component)((Component)((Component)player.playerBodyAnimator).transform.parent).transform.Find("LOD1")).gameObject.GetComponent<SkinnedMeshRenderer>()).material;
		}

		private static void TogglePlayerBadges(bool enabled)
		{
			if ((Object)(object)s_localPlayerBetaBadge != (Object)null)
			{
				((Renderer)s_localPlayerBetaBadge.GetComponent<MeshRenderer>()).enabled = enabled;
			}
			if ((Object)(object)s_localPlayerLevelBadge != (Object)null)
			{
				((Renderer)s_localPlayerLevelBadge.GetComponent<MeshRenderer>()).enabled = enabled;
			}
			else
			{
				Debug.LogError((object)"[MoreEmotes-Sligili] Couldn't find the level badge");
			}
		}

		private static bool CheckIfTooManyEmotesIsPlaying(PlayerControllerB player)
		{
			//IL_000a: 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)
			Animator playerBodyAnimator = player.playerBodyAnimator;
			AnimatorStateInfo currentAnimatorStateInfo = playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
			return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Dance1") && player.performingEmote && GetAnimatorEmoteClipName(playerBodyAnimator) != "Dance1";
		}

		private static string GetAnimatorEmoteClipName(Animator animator)
		{
			AnimatorClipInfo[] currentAnimatorClipInfo = animator.GetCurrentAnimatorClipInfo(1);
			return ((Object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip).name;
		}

		private static void TurnControllerIntoAnOverrideController(RuntimeAnimatorController controller)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (!(controller is AnimatorOverrideController))
			{
				controller = (RuntimeAnimatorController)new AnimatorOverrideController(controller);
			}
		}

		public static void UpdateWheelKeybinds()
		{
			if (UseConfigFile)
			{
				EmoteWheelKeyboard = ConfigFile_WheelKeybind;
				EmoteWheelController = ConfigFile_WheelKeybind_controller;
				return;
			}
			if (!PlayerPrefs.HasKey("Emote_Wheel_c"))
			{
				PlayerPrefs.SetString("Emote_Wheel_c", ConfigFile_WheelKeybind_controller);
			}
			EmoteWheelController = PlayerPrefs.GetString("Emote_Wheel_c");
			if (!PlayerPrefs.HasKey("Emote_Wheel"))
			{
				PlayerPrefs.SetString("Emote_Wheel", ConfigFile_WheelKeybind);
			}
			EmoteWheelKeyboard = PlayerPrefs.GetString("Emote_Wheel");
			if (!PlayerPrefs.HasKey("InvCheck"))
			{
				PlayerPrefs.SetInt("InvCheck", ConfigFile_InventoryCheck ? 1 : 0);
			}
			ConfigFile_InventoryCheck = PlayerPrefs.GetInt("InvCheck") == 1;
		}

		[HarmonyPatch(typeof(MenuManager), "Start")]
		[HarmonyPostfix]
		private static void MenuStart(MenuManager __instance)
		{
			D.Debug = true;
			try
			{
				InstantiateSettingsMenu(((Component)((Component)__instance).transform.parent).transform.Find("MenuContainer"));
			}
			catch (Exception ex)
			{
				if (!s_isFirstTimeOnMenu)
				{
					s_isFirstTimeOnMenu = true;
				}
				else
				{
					Debug.LogError((object)(ex.Message + "\n[MoreEmotes-Sligili] Couldn't find MenuContainer"));
				}
			}
		}

		[HarmonyPatch(typeof(RoundManager), "Awake")]
		[HarmonyPostfix]
		private static void AwakePost(RoundManager __instance)
		{
			if (!PlayerPrefs.HasKey("InvCheck"))
			{
				PlayerPrefs.SetInt("InvCheck", ConfigFile_InventoryCheck ? 1 : 0);
			}
			UpdateWheelKeybinds();
			GameObject gameObject = ((Component)((Component)GameObject.Find("Systems").gameObject.transform.Find("UI")).gameObject.transform.Find("Canvas")).gameObject;
			InstantiateSettingsMenu(gameObject.transform.Find("QuickMenu"));
			s_selectionWheel = Object.Instantiate<GameObject>(WheelPrefab, gameObject.transform).AddComponent<EmoteWheel>();
			s_customSignInputField = Object.Instantiate<GameObject>(SignUIPrefab, gameObject.transform).AddComponent<SignUI>();
			EmoteWheel.Keybinds = new string[ConfigFile_Keybinds.Length + 1];
			EmoteWheel.Keybinds = ConfigFile_Keybinds;
			s_isPlayerFirstFrame = true;
		}

		[HarmonyPatch(typeof(HUDManager), "EnableChat_performed")]
		[HarmonyPrefix]
		private static bool OpenChatPrefix()
		{
			if (s_customSignInputField.IsSignUIOpen)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
		[HarmonyPrefix]
		private static bool SubmitChatPrefix()
		{
			if (s_customSignInputField.IsSignUIOpen)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(PlayerControllerB __instance)
		{
			((Component)((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel")).transform.Find("metarig")).gameObject.AddComponent<MoreEmotesEvents>().Player = __instance;
			s_defaultPlayerSpeed = __instance.movementSpeed;
			((Component)__instance).gameObject.AddComponent<CustomAnimationObjects>();
			SpawnSign(__instance);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(PlayerControllerB __instance)
		{
			if (!__instance.isPlayerControlled || !((NetworkBehaviour)__instance).IsOwner)
			{
				__instance.playerBodyAnimator.runtimeAnimatorController = others;
				TurnControllerIntoAnOverrideController(__instance.playerBodyAnimator.runtimeAnimatorController);
				return;
			}
			if ((Object)(object)__instance.playerBodyAnimator != (Object)(object)local)
			{
				if (s_isPlayerFirstFrame)
				{
					SpawnLegs(__instance);
				}
				__instance.playerBodyAnimator.runtimeAnimatorController = local;
				if (s_isPlayerFirstFrame)
				{
					OnFirstLocalPlayerFrameWithNewAnimator(__instance);
				}
				if (s_isPlayerSpawning)
				{
					__instance.SpawnPlayerAnimation();
					s_isPlayerSpawning = false;
				}
			}
			if (!IncompatibleStuff)
			{
				if ((bool)Ref.Method(__instance, "CheckConditionsForEmote") && __instance.performingEmote)
				{
					switch (s_currentEmoteID)
					{
					case 6:
						__instance.movementSpeed = s_defaultPlayerSpeed / 2f;
						break;
					case 9:
						__instance.movementSpeed = s_defaultPlayerSpeed / 3f;
						break;
					}
				}
				else
				{
					__instance.movementSpeed = s_defaultPlayerSpeed;
				}
			}
			__instance.localArmsRotationTarget = (LocalArmsSeparatedFromCamera ? (__instance.localArmsRotationTarget = s_freeArmsTarget) : (__instance.localArmsRotationTarget = s_lockedArmsTarget));
			CheckWheelInput(EmoteWheelKeyboard, EmoteWheelController, __instance);
			if (!__instance.quickMenuManager.isMenuOpen && !IsEmoteWheelOpen)
			{
				CheckEmoteInput(ConfigFile_Keybinds[2], needsEmptyHands: false, 3, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[3], needsEmptyHands: true, 4, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[4], needsEmptyHands: true, 5, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[5], needsEmptyHands: false, 6, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[6], needsEmptyHands: true, 7, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[7], needsEmptyHands: true, 8, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[8], needsEmptyHands: true, 9, __instance);
				CheckEmoteInput(ConfigFile_Keybinds[9], needsEmptyHands: true, 10, __instance);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPrefix]
		private static void UpdatePrefix(PlayerControllerB __instance)
		{
			if (__instance.performingEmote)
			{
				s_wasPerformingEmote[__instance.playerClientId] = true;
			}
			if (!__instance.performingEmote && s_wasPerformingEmote[__instance.playerClientId])
			{
				s_wasPerformingEmote[__instance.playerClientId] = false;
				ResetIKWeights(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
		[HarmonyPrefix]
		private static void OnLocalPlayerSpawn(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
			{
				s_isPlayerSpawning = true;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "CheckConditionsForEmote")]
		[HarmonyPrefix]
		private static bool CheckConditionsPrefix(ref bool __result, PlayerControllerB __instance)
		{
			bool flag = (bool)Ref.GetInstanceField(typeof(PlayerControllerB), __instance, "isJumping");
			bool flag2 = (bool)Ref.GetInstanceField(typeof(PlayerControllerB), __instance, "isWalking");
			if (s_currentEmoteID == 6 || s_currentEmoteID == 9)
			{
				__result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !flag && __instance.moveInputVector.x == 0f && !__instance.isSprinting && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu && !__instance.isTypingChat;
				return false;
			}
			if (s_currentEmoteID == 10 || s_currentEmoteID == 1010)
			{
				__result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !flag && !flag2 && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PerformEmote")]
		[HarmonyPrefix]
		private static bool PerformEmotePrefix(CallbackContext context, int emoteID, PlayerControllerB __instance)
		{
			if ((emoteID < 0 || CheckIfTooManyEmotesIsPlaying(__instance)) && emoteID > 2)
			{
				return false;
			}
			if ((!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer)
			{
				return false;
			}
			if (s_customSignInputField.IsSignUIOpen && emoteID != 1010)
			{
				return false;
			}
			if (emoteID > 0 && emoteID < 3 && !IsEmoteWheelOpen && !((CallbackContext)(ref context)).performed)
			{
				return false;
			}
			int[] array = s_doubleEmotesIDS;
			foreach (int num in array)
			{
				int num2 = num + _AlternateEmoteIDOffset;
				bool flag = (UseConfigFile ? ConfigFile_InventoryCheck : (PlayerPrefs.GetInt("InvCheck") == 1));
				if (emoteID == num && s_currentEmoteID == emoteID && __instance.performingEmote && (!__instance.isHoldingObject || !flag))
				{
					if (emoteID == num)
					{
						emoteID += _AlternateEmoteIDOffset;
					}
					else
					{
						emoteID -= 1000;
					}
				}
			}
			if ((s_currentEmoteID != emoteID && emoteID < 3) || !__instance.performingEmote)
			{
				ResetIKWeights(__instance);
			}
			if (!(bool)Ref.Method(__instance, "CheckConditionsForEmote"))
			{
				return false;
			}
			if (__instance.timeSinceStartingEmote < 0.5f)
			{
				return false;
			}
			s_currentEmoteID = emoteID;
			Action action = delegate
			{
				__instance.timeSinceStartingEmote = 0f;
				__instance.playerBodyAnimator.SetInteger("emoteNumber", emoteID);
				__instance.performingEmote = true;
				__instance.StartPerformingEmoteServerRpc();
				s_syncAnimator.UpdateEmoteIDForOthers(emoteID);
				TogglePlayerBadges(enabled: false);
			};
			switch (emoteID)
			{
			case 9:
				action = (Action)Delegate.Combine(action, (Action)delegate
				{
					UpdateLegsMaterial(__instance);
				});
				break;
			case 10:
				action = (Action)Delegate.Combine(action, (Action)delegate
				{
					((Component)s_customSignInputField).gameObject.SetActive(true);
				});
				break;
			}
			action();
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "StopPerformingEmoteServerRpc")]
		[HarmonyPostfix]
		private static void StopPerformingEmoteServerPrefix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
			{
				__instance.playerBodyAnimator.SetInteger("emoteNumber", 0);
			}
			TogglePlayerBadges(enabled: true);
			s_syncAnimator.UpdateEmoteIDForOthers(0);
			s_currentEmoteID = 0;
		}
	}
}
namespace MoreEmotes.Scripts
{
	public class MoreEmotesEvents : MonoBehaviour
	{
		private Animator _playerAnimator;

		private AudioSource _playerAudioSource;

		public static AudioClip[] ClapSounds = (AudioClip[])(object)new AudioClip[2];

		public PlayerControllerB Player;

		private void Start()
		{
			_playerAnimator = ((Component)this).GetComponent<Animator>();
			_playerAudioSource = Player.movementAudio;
		}

		public void PlayClapSound()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (Player.performingEmote)
			{
				int currentEmoteID = GetCurrentEmoteID();
				if (!((NetworkBehaviour)Player).IsOwner || !Player.isPlayerControlled || currentEmoteID == 4)
				{
					bool flag = Player.isInHangarShipRoom && Player.playersManager.hangarDoorsClosed;
					RoundManager.Instance.PlayAudibleNoise(((Component)Player).transform.position, 22f, 0.6f, 0, flag, 6);
					_playerAudioSource.pitch = Random.Range(0.59f, 0.79f);
					_playerAudioSource.PlayOneShot(ClapSounds[Random.Range(0, ClapSounds.Length)]);
				}
			}
		}

		public void PlayFootstepSound()
		{
			if (Player.performingEmote)
			{
				int currentEmoteID = GetCurrentEmoteID();
				if ((!((NetworkBehaviour)Player).IsOwner || !Player.isPlayerControlled || currentEmoteID == 6 || currentEmoteID == 8 || currentEmoteID == 9) && ((Vector2)(ref Player.moveInputVector)).sqrMagnitude == 0f)
				{
					Player.PlayFootstepLocal();
					Player.PlayFootstepServer();
				}
			}
		}

		private int GetCurrentEmoteID()
		{
			int num = _playerAnimator.GetInteger("emoteNumber");
			if (num >= 1000)
			{
				num -= 1000;
			}
			return num;
		}
	}
	public class SignEmoteText : NetworkBehaviour
	{
		private PlayerControllerB _playerInstance;

		private TextMeshPro _signModelText;

		public string Text => ((TMP_Text)_signModelText).text;

		private void Start()
		{
			_playerInstance = ((Component)this).GetComponent<PlayerControllerB>();
			_signModelText = ((Component)((Component)_playerInstance).transform.Find("ScavengerModel").Find("metarig").Find("Sign")
				.Find("Text")).GetComponent<TextMeshPro>();
		}

		public void UpdateSignText(string newText)
		{
			if (((NetworkBehaviour)_playerInstance).IsOwner && _playerInstance.isPlayerControlled)
			{
				UpdateSignTextServerRpc(newText);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void UpdateSignTextServerRpc(string newText)
		{
			UpdateSignTextClientRpc(newText);
		}

		[ClientRpc]
		private void UpdateSignTextClientRpc(string newText)
		{
			((TMP_Text)_signModelText).text = newText;
		}
	}
	public class EmoteWheel : MonoBehaviour
	{
		private RectTransform _graphics_selectedBlock;

		private RectTransform _graphics_selectionArrow;

		private Text _graphics_emoteInformation;

		private Text _graphics_pageInformation;

		private int _blocksNumber = 8;

		private int _selectedBlock = 1;

		private float _changePageCooldown = 0.1f;

		private float _selectionArrowLerpSpeed = 30f;

		private float _angle;

		private GameObject[] _pages;

		public float WheelMovementDeadzone = 3.3f;

		public float WheelMovementDeadzoneController = 0.7f;

		public static string[] Keybinds;

		private Vector2 _wheelCenter;

		private Vector2 _lastMouseCoords;

		public int SelectedPageNumber { get; private set; }

		public int SelectedEmoteID { get; private set; }

		public bool IsUsingController { get; private set; }

		private void Awake()
		{
			GetVanillaKeybinds();
			FindGraphics();
			FindPages(((Component)this).gameObject.transform.Find("FunctionalContent"));
			UpdatePageInfo();
		}

		private void OnEnable()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_wheelCenter = new Vector2((float)(Screen.width / 2), (float)(Screen.height / 2));
			Mouse.current.WarpCursorPosition(_wheelCenter);
		}

		private void GetVanillaKeybinds()
		{
			PlayerInput component = GameObject.Find("PlayerSettingsObject").GetComponent<PlayerInput>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)" MoreEmotes: PlayerSettingsObject is null");
				return;
			}
			Keybinds[0] = InputActionRebindingExtensions.GetBindingDisplayString(component.currentActionMap.FindAction("Emote1", false), 0, (DisplayStringOptions)0);
			Keybinds[1] = InputActionRebindingExtensions.GetBindingDisplayString(component.currentActionMap.FindAction("Emote2", false), 0, (DisplayStringOptions)0);
		}

		private void FindGraphics()
		{
			_graphics_selectionArrow = ((Component)((Component)((Component)this).gameObject.transform.Find("Graphics")).gameObject.transform.Find("SelectionArrow")).gameObject.GetComponent<RectTransform>();
			_graphics_selectedBlock = ((Component)((Component)this).gameObject.transform.Find("SelectedEmote")).gameObject.GetComponent<RectTransform>();
			_graphics_emoteInformation = ((Component)((Component)((Component)this).gameObject.transform.Find("Graphics")).gameObject.transform.Find("EmoteInfo")).GetComponent<Text>();
			_graphics_pageInformation = ((Component)((Component)((Component)this).gameObject.transform.Find("Graphics")).gameObject.transform.Find("PageNumber")).GetComponent<Text>();
		}

		private void FindPages(Transform contentParent)
		{
			_pages = (GameObject[])(object)new GameObject[((Component)contentParent).transform.childCount];
			_graphics_pageInformation.text = "< Page " + (SelectedPageNumber + 1) + "/" + _pages.Length + " >";
			for (int i = 0; i < ((Component)contentParent).transform.childCount; i++)
			{
				_pages[i] = ((Component)((Component)contentParent).transform.GetChild(i)).gameObject;
			}
		}

		private void Update()
		{
			ControllerInput();
			if (!IsUsingController)
			{
				MouseInput();
			}
			Cursor.visible = !IsUsingController;
			UpdateSelectionArrow();
			PageSelection();
			SelectedEmoteID = _selectedBlock + Mathf.RoundToInt((float)(_blocksNumber / 4)) + _blocksNumber * SelectedPageNumber;
			UpdateEmoteInfo();
		}

		private unsafe void ControllerInput()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (Gamepad.all.Count == 0)
			{
				IsUsingController = false;
				return;
			}
			float num = ((InputControl<float>)(object)((Vector2Control)Gamepad.current.rightStick).x).ReadUnprocessedValue();
			float num2 = ((InputControl<float>)(object)((Vector2Control)Gamepad.current.rightStick).y).ReadUnprocessedValue();
			if (Mathf.Abs(num) < WheelMovementDeadzoneController && Mathf.Abs(num2) < WheelMovementDeadzoneController)
			{
				if (System.Runtime.CompilerServices.Unsafe.Read<Vector2>((void*)((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).value) != _lastMouseCoords)
				{
					IsUsingController = false;
				}
			}
			else
			{
				IsUsingController = true;
				_lastMouseCoords = System.Runtime.CompilerServices.Unsafe.Read<Vector2>((void*)((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).value);
				WheelSelection(Vector2.zero, num, num2);
			}
		}

		private void MouseInput()
		{
			//IL_0002: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!(Vector2.Distance(_wheelCenter, ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue()) < WheelMovementDeadzone))
			{
				WheelSelection(_wheelCenter, ((InputControl<float>)(object)((Pointer)Mouse.current).position.x).ReadValue(), ((InputControl<float>)(object)((Pointer)Mouse.current).position.y).ReadValue());
			}
		}

		private void WheelSelection(Vector2 origin, float xAxisValue, float yAxisValue)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			bool flag = xAxisValue > origin.x;
			bool flag2 = yAxisValue > origin.y;
			int num = ((!flag) ? (flag2 ? 2 : 3) : (flag2 ? 1 : 4));
			float num2 = (yAxisValue - origin.y) / (xAxisValue - origin.x);
			float num3 = 180 * (num - ((num <= 2) ? 1 : 2));
			_angle = Mathf.Atan(num2) * (180f / (float)Math.PI) + num3;
			if (_angle == 90f)
			{
				_angle = 270f;
			}
			else if (_angle == 270f)
			{
				_angle = 90f;
			}
			float num4 = 360 / _blocksNumber;
			_selectedBlock = Mathf.RoundToInt((_angle - num4 * 1.5f) / num4);
			((Transform)_graphics_selectedBlock).localRotation = Quaternion.Euler(((Component)this).transform.rotation.z, ((Component)this).transform.rotation.y, num4 * (float)_selectedBlock);
		}

		private void PageSelection()
		{
			UpdatePageInfo();
			if (_changePageCooldown > 0f)
			{
				_changePageCooldown -= Time.deltaTime;
				return;
			}
			int num;
			if (IsUsingController)
			{
				if (!Gamepad.current.dpad.left.isPressed && !Gamepad.current.dpad.right.isPressed)
				{
					return;
				}
				num = (Gamepad.current.dpad.left.isPressed ? 1 : (-1));
			}
			else
			{
				if (((InputControl<float>)(object)((Vector2Control)Mouse.current.scroll).y).ReadValue() == 0f)
				{
					return;
				}
				num = ((((InputControl<float>)(object)((Vector2Control)Mouse.current.scroll).y).ReadValue() > 0f) ? 1 : (-1));
			}
			GameObject[] pages = _pages;
			foreach (GameObject val in pages)
			{
				val.SetActive(false);
			}
			SelectedPageNumber = (SelectedPageNumber + num + _pages.Length) % _pages.Length;
			_pages[SelectedPageNumber].SetActive(true);
			_changePageCooldown = ((!IsUsingController) ? 0.1f : 0.3f);
		}

		private void UpdatePageInfo()
		{
			_graphics_pageInformation.text = $"<color=#fe6b02><</color> Page {SelectedPageNumber + 1}/{_pages.Length} <color=#fe6b02>></color>";
		}

		private void UpdateEmoteInfo()
		{
			string text = ((SelectedEmoteID > Keybinds.Length) ? "" : Keybinds[SelectedEmoteID - 1]);
			int num = 0;
			foreach (Emotes value in Enum.GetValues(typeof(Emotes)))
			{
				if (value >= Emotes.Dance && value < (Emotes)64)
				{
					num++;
				}
			}
			string text2 = ((SelectedEmoteID > num) ? "EMPTY" : ((Emotes)SelectedEmoteID).ToString().Replace("_", " "));
			if (SelectedEmoteID > 2 && SelectedEmoteID <= Keybinds.Length)
			{
				if (!PlayerPrefs.HasKey(text2.Replace(" ", "_")))
				{
					PlayerPrefs.SetString(text2.Replace(" ", "_"), (SelectedEmoteID > Keybinds.Length) ? "" : Keybinds[SelectedEmoteID - 1]);
				}
				else
				{
					text = PlayerPrefs.GetString(text2.Replace(" ", "_"));
				}
			}
			text = "<size=120>[" + text + "]</size>";
			_graphics_emoteInformation.text = text2 + "\n" + text.ToUpper();
		}

		private void UpdateSelectionArrow()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			float num = 360 / _blocksNumber;
			Quaternion val = Quaternion.Euler(0f, 0f, _angle - num * 2f);
			((Transform)_graphics_selectionArrow).localRotation = Quaternion.Lerp(((Transform)_graphics_selectionArrow).localRotation, val, Time.deltaTime * _selectionArrowLerpSpeed);
		}
	}
	public class RebindButton : MonoBehaviour
	{
		public static string[] ConfigFile_Keybinds;

		private string _defaultKey;

		private string _playerPrefsString;

		private Transform _waitingForInput;

		private Text _keyInfo;

		public bool IsControllerButton { get; private set; } = false;


		private void Start()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			string text = ((Component)((Component)this).gameObject.transform.Find("Description")).GetComponent<Text>().text;
			IsControllerButton = GetControllerFlag();
			_playerPrefsString = ((Component)((Component)this).gameObject.transform.Find("Description")).GetComponent<Text>().text.Replace(" ", "_") + (IsControllerButton ? "_c" : "");
			_defaultKey = GetDefaultKey(text);
			FindComponents();
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(GetKey));
			if (!PlayerPrefs.HasKey(_playerPrefsString))
			{
				PlayerPrefs.SetString(_playerPrefsString, _defaultKey);
			}
			SetKeybind(PlayerPrefs.GetString(_playerPrefsString));
		}

		private string GetDefaultKey(string emoteName)
		{
			if (Enum.TryParse<Emotes>(emoteName.Replace(" ", "_"), out var result))
			{
				return ConfigFile_Keybinds[(int)(result - 1)];
			}
			return IsControllerButton ? "leftshoulder" : "V";
		}

		private bool GetControllerFlag()
		{
			Transform val = ((Component)this).gameObject.transform.Find("Description").Find("Subtext");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Text val2 = default(Text);
			if (((Component)val).TryGetComponent<Text>(ref val2))
			{
				return val2.text.Equals("(Controller)", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private void FindComponents()
		{
			((Component)((Component)((Component)this).transform.parent).transform.Find("Delete")).gameObject.AddComponent<DeleteButton>();
			_keyInfo = ((Component)((Component)this).transform.Find("InputText")).GetComponent<Text>();
			_waitingForInput = ((Component)this).transform.Find("wait");
		}

		public void SetKeybind(string key)
		{
			List<string> list = new List<string> { "up", "down", "left", "right" };
			if (list.Contains(key.ToLower()) && key.Length < 5)
			{
				key = "dpad/" + key;
			}
			PlayerPrefs.SetString(_playerPrefsString, key);
			_keyInfo.text = key.ToUpper();
			((MonoBehaviour)this).StopAllCoroutines();
			((Component)_waitingForInput).gameObject.SetActive(false);
		}

		private void GetKey()
		{
			((Component)_waitingForInput).gameObject.SetActive(true);
			((MonoBehaviour)this).StartCoroutine(WaitForKey(delegate(string key)
			{
				SetKeybind(key);
			}));
		}

		private IEnumerator WaitForKey(Action<string> callback)
		{
			while (!((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame || (!((InputDevice)Gamepad.current).wasUpdatedThisFrame && !InputControlExtensions.IsActuated((InputControl)(object)Gamepad.current.leftStick, 0f) && !InputControlExtensions.IsActuated((InputControl)(object)Gamepad.current.rightStick, 0f)))
			{
				yield return (object)new WaitForEndOfFrame();
				Observable.CallOnce<InputControl>(InputSystem.onAnyButtonPress, (Action<InputControl>)delegate(InputControl ctrl)
				{
					callback(((ctrl.device == Gamepad.current && IsControllerButton) || (ctrl.device == Keyboard.current && !IsControllerButton)) ? ctrl.name : _defaultKey);
				});
			}
		}
	}
	public class DeleteButton : MonoBehaviour
	{
		private void Start()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			RebindButton _rebindButton = ((Component)((Component)((Component)this).transform.parent).transform.Find("Button")).GetComponent<RebindButton>();
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				_rebindButton.SetKeybind(string.Empty);
			});
		}
	}
	public class ToggleButton : MonoBehaviour
	{
		private Toggle _toggle;

		public static bool s_InventoryCheck;

		public string PlayerPrefsString;

		private void Start()
		{
			_toggle = ((Component)this).GetComponent<Toggle>();
			_toggle.isOn = s_InventoryCheck;
			((UnityEvent<bool>)(object)_toggle.onValueChanged).AddListener((UnityAction<bool>)SetNewValue);
			if (!PlayerPrefs.HasKey(PlayerPrefsString))
			{
				SetNewValue(s_InventoryCheck);
			}
		}

		public void SetNewValue(bool arg)
		{
			PlayerPrefs.SetInt(PlayerPrefsString, arg ? 1 : 0);
		}
	}
	public class EnableDisableButton : MonoBehaviour
	{
		public GameObject[] ToAlternateUI = (GameObject[])(object)new GameObject[1];

		private void Start()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				GameObject[] toAlternateUI = ToAlternateUI;
				foreach (GameObject val in toAlternateUI)
				{
					val.SetActive((!val.activeInHierarchy) ? true : false);
				}
			});
			if (((Object)((Component)this).gameObject).name.Equals("BackButton", StringComparison.OrdinalIgnoreCase))
			{
				ToAlternateUI[0] = ((Component)((Component)this).transform.parent).gameObject;
			}
			if (((Object)((Component)this).gameObject).name.Equals("MoreEmotesButton(Clone)", StringComparison.OrdinalIgnoreCase))
			{
				ToAlternateUI[0] = ((Component)((Component)((Component)this).transform.parent).gameObject.transform.Find("MoreEmotesPanel(Clone)")).gameObject;
			}
		}
	}
	public class SetupUI : MonoBehaviour
	{
		public static bool UseConfigFile;

		public static bool InventoryCheck;

		private void Awake()
		{
			Transform settingsUIPanel = ((Component)this).transform.Find("MoreEmotesPanel(Clone)");
			((Component)settingsUIPanel.Find("Version")).GetComponent<Text>().text = "1.3.3 - Sligili";
			SetupOpenSettingsButton();
			SetupBackButton();
			SetupRebindButtons(((Component)settingsUIPanel).transform.Find("KeybindButtons"));
			SetupRebindButtons(((Component)((Component)((Component)settingsUIPanel).transform.Find("Scroll View")).transform.Find("Viewport")).transform.Find("Content"));
			SetupInventoryCheckToggle();
			SetupUseConfigFileToggle();
			void SetupBackButton()
			{
				((Component)((Component)settingsUIPanel).transform.Find("BackButton")).gameObject.AddComponent<EnableDisableButton>();
			}
			void SetupInventoryCheckToggle()
			{
				((Component)((Component)settingsUIPanel).transform.Find("Inv")).gameObject.AddComponent<ToggleButton>().PlayerPrefsString = "InvCheck";
			}
			void SetupOpenSettingsButton()
			{
				((Component)((Component)this).transform.Find("MoreEmotesButton(Clone)")).gameObject.AddComponent<EnableDisableButton>();
			}
			static void SetupRebindButtons(Transform ButtonsParent)
			{
				Transform[] array = (Transform[])(object)new Transform[ButtonsParent.childCount];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = ButtonsParent.GetChild(i);
				}
				Transform[] array2 = array;
				foreach (Transform val in array2)
				{
					((Component)val.Find("Button")).gameObject.AddComponent<RebindButton>();
				}
			}
			void SetupUseConfigFileToggle()
			{
				((Component)((Component)settingsUIPanel).transform.Find("cfg")).gameObject.GetComponent<Toggle>().isOn = UseConfigFile;
			}
		}

		private void Update()
		{
			EmotePatch.UpdateWheelKeybinds();
		}
	}
	public class SignUI : MonoBehaviour
	{
		public PlayerControllerB Player;

		private TMP_InputField _inputField;

		private Text _charactersLeftText;

		private TMP_Text _previewText;

		private Button _submitButton;

		private Button _cancelButton;

		public bool IsSignUIOpen;

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			FindComponents();
			((UnityEvent)_submitButton.onClick).AddListener(new UnityAction(SubmitText));
			((UnityEvent)_cancelButton.onClick).AddListener((UnityAction)delegate
			{
				Close(cancelAction: true);
			});
			((UnityEvent<string>)(object)_inputField.onValueChanged).AddListener((UnityAction<string>)delegate(string fieldText)
			{
				UpdatePreviewText(fieldText);
				UpdateCharactersLeftText();
			});
		}

		private void OnEnable()
		{
			Player.isTypingChat = true;
			IsSignUIOpen = true;
			((Selectable)_inputField).Select();
			_inputField.text = string.Empty;
			_previewText.text = "PREVIEW";
			Player.disableLookInput = true;
		}

		private void Update()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)2;
			if (!Player.performingEmote)
			{
				Close(cancelAction: true);
			}
			if (((ButtonControl)Keyboard.current[(Key)2]).wasPressedThisFrame && !((ButtonControl)Keyboard.current[(Key)51]).isPressed)
			{
				SubmitText();
			}
			if (Player.quickMenuManager.isMenuOpen || EmotePatch.IsEmoteWheelOpen || InputControlExtensions.IsPressed(((InputControl)Mouse.current)["rightButton"], 0f))
			{
				Close(cancelAction: true);
			}
			if (Gamepad.all.Count != 0)
			{
				if (Gamepad.current.buttonWest.isPressed || Gamepad.current.startButton.isPressed)
				{
					SubmitText();
				}
				if (Gamepad.current.buttonEast.isPressed || Gamepad.current.selectButton.isPressed)
				{
					Close(cancelAction: true);
				}
			}
		}

		private void FindComponents()
		{
			_inputField = ((Component)((Component)this).transform.Find("InputField")).GetComponent<TMP_InputField>();
			_charactersLeftText = ((Component)((Component)this).transform.Find("CharsLeft")).GetComponent<Text>();
			_submitButton = ((Component)((Component)this).transform.Find("Submit")).GetComponent<Button>();
			_cancelButton = ((Component)((Component)this).transform.Find("Cancel")).GetComponent<Button>();
			_previewText = ((Component)((Component)((Component)this).transform.Find("Sign")).transform.Find("Text")).GetComponent<TMP_Text>();
		}

		private void UpdateCharactersLeftText()
		{
			_charactersLeftText.text = $"CHARACTERS LEFT: <color=yellow>{_inputField.characterLimit - _inputField.text.Length}</color>";
		}

		private void UpdatePreviewText(string text)
		{
			_previewText.text = text;
		}

		private void SubmitText()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (_inputField.text.Equals(string.Empty))
			{
				Close(cancelAction: true);
				return;
			}
			D.L("Submitted " + _inputField.text + " to server");
			((Component)Player).GetComponent<SignEmoteText>().UpdateSignText(_inputField.text);
			float num = 0.5f;
			if (Player.timeSinceStartingEmote > num)
			{
				Player.PerformEmote(default(CallbackContext), 1010);
			}
			Close(cancelAction: false);
		}

		private void Close(bool cancelAction)
		{
			Player.isTypingChat = false;
			IsSignUIOpen = false;
			if (cancelAction)
			{
				Player.performingEmote = false;
				Player.StopPerformingEmoteServerRpc();
			}
			if (!Player.quickMenuManager.isMenuOpen)
			{
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
			}
			Player.disableLookInput = false;
			((Component)this).gameObject.SetActive(false);
		}
	}
	public class SyncAnimatorToOthers : NetworkBehaviour
	{
		private PlayerControllerB _player;

		private void Start()
		{
			_player = ((Component)this).GetComponent<PlayerControllerB>();
		}

		public void UpdateEmoteIDForOthers(int newID)
		{
			if (((NetworkBehaviour)_player).IsOwner && _player.isPlayerControlled)
			{
				UpdateCurrentEmoteIDServerRpc(newID);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void UpdateCurrentEmoteIDServerRpc(int newID)
		{
			UpdateCurrentEmoteIDClientRpc(newID);
		}

		[ClientRpc]
		private void UpdateCurrentEmoteIDClientRpc(int newID)
		{
			if (!((NetworkBehaviour)_player).IsOwner)
			{
				_player.playerBodyAnimator.SetInteger("emoteNumber", newID);
			}
		}
	}
	public class CustomAnimationObjects : MonoBehaviour
	{
		private PlayerControllerB _player;

		private MeshRenderer _sign;

		private GameObject _signText;

		private SkinnedMeshRenderer _legs;

		private void Start()
		{
			_player = ((Component)this).GetComponent<PlayerControllerB>();
		}

		private void Update()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_sign == (Object)null || (Object)(object)_signText == (Object)null)
			{
				FindSign();
				return;
			}
			((Component)_sign).transform.localPosition = ((Component)_sign).transform.parent.Find("spine").localPosition;
			if ((Object)(object)_legs == (Object)null && ((NetworkBehaviour)_player).IsOwner && _player.isPlayerControlled)
			{
				FindLegs();
				return;
			}
			DisableEverything();
			if (!_player.performingEmote)
			{
				return;
			}
			switch (_player.playerBodyAnimator.GetInteger("emoteNumber"))
			{
			case 10:
			case 1010:
				((Renderer)_sign).enabled = true;
				if (!_signText.activeSelf)
				{
					_signText.SetActive(true);
				}
				if (((NetworkBehaviour)_player).IsOwner)
				{
					EmotePatch.LocalArmsSeparatedFromCamera = true;
				}
				break;
			case 9:
				if ((Object)(object)_legs != (Object)null)
				{
					((Renderer)_legs).enabled = true;
				}
				if (((NetworkBehaviour)_player).IsOwner)
				{
					EmotePatch.LocalArmsSeparatedFromCamera = true;
				}
				break;
			}
		}

		private void DisableEverything()
		{
			if ((Object)(object)_legs != (Object)null)
			{
				((Renderer)_legs).enabled = false;
			}
			((Renderer)_sign).enabled = false;
			if (_signText.activeSelf)
			{
				_signText.SetActive(false);
			}
			if (((NetworkBehaviour)_player).IsOwner && _player.isPlayerControlled)
			{
				EmotePatch.LocalArmsSeparatedFromCamera = false;
			}
		}

		private void FindSign()
		{
			_sign = ((Component)((Component)_player).transform.Find("ScavengerModel").Find("metarig").Find("Sign")).GetComponent<MeshRenderer>();
			_signText = ((Component)((Component)_sign).transform.Find("Text")).gameObject;
		}

		private void FindLegs()
		{
			_legs = ((Component)((Component)_player).transform.Find("ScavengerModel").Find("LEGS")).GetComponent<SkinnedMeshRenderer>();
		}
	}
}

mods/tinyhoot-ShipLoot-1.0.0/plugins/ShipLoot/ShipLoot.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShipLoot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("ShipLoot")]
[assembly: AssemblyCopyright("Copyright © tinyhoot 2023")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ShipLoot
{
	[BepInPlugin("com.github.tinyhoot.ShipLoot", "ShipLoot", "1.0")]
	internal class ShipLoot : BaseUnityPlugin
	{
		public const string GUID = "com.github.tinyhoot.ShipLoot";

		public const string NAME = "ShipLoot";

		public const string VERSION = "1.0";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.github.tinyhoot.ShipLoot").PatchAll(Assembly.GetExecutingAssembly());
		}
	}
}
namespace ShipLoot.Patches
{
	[HarmonyPatch]
	internal class HudManagerPatcher
	{
		private static GameObject _totalCounter;

		private static TextMeshProUGUI _textMesh;

		private static float _displayTimeLeft;

		private const float DisplayTime = 5f;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HUDManager), "PingScan_performed")]
		private static void OnScan(HUDManager __instance, CallbackContext context)
		{
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && __instance.CanPlayerScan() && !(__instance.playerPingingScan > -0.5f) && (StartOfRound.Instance.inShipPhase || GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom))
			{
				if (!Object.op_Implicit((Object)(object)_totalCounter))
				{
					CopyValueCounter();
				}
				float num = CalculateLootValue();
				((TMP_Text)_textMesh).text = $"SHIP: ${num:F0}";
				_displayTimeLeft = 5f;
				if (!_totalCounter.activeSelf)
				{
					((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(ShipLootCoroutine());
				}
			}
		}

		private static IEnumerator ShipLootCoroutine()
		{
			_totalCounter.SetActive(true);
			while (_displayTimeLeft > 0f)
			{
				float displayTimeLeft = _displayTimeLeft;
				_displayTimeLeft = 0f;
				yield return (object)new WaitForSeconds(displayTimeLeft);
			}
			_totalCounter.SetActive(false);
		}

		private static float CalculateLootValue()
		{
			List<GrabbableObject> list = (from obj in GameObject.Find("/Environment/HangarShip").GetComponentsInChildren<GrabbableObject>()
				where ((Object)obj).name != "ClipboardManual" && ((Object)obj).name != "StickyNoteItem"
				select obj).ToList();
			ShipLoot.Log.LogDebug((object)"Calculating total ship scrap value.");
			CollectionExtensions.Do<GrabbableObject>((IEnumerable<GrabbableObject>)list, (Action<GrabbableObject>)delegate(GrabbableObject scrap)
			{
				ShipLoot.Log.LogDebug((object)$"{((Object)scrap).name} - ${scrap.scrapValue}");
			});
			return list.Sum((GrabbableObject scrap) => scrap.scrapValue);
		}

		private static void CopyValueCounter()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter");
			if (!Object.op_Implicit((Object)(object)val))
			{
				ShipLoot.Log.LogError((object)"Failed to find ValueCounter object to copy!");
			}
			_totalCounter = Object.Instantiate<GameObject>(val.gameObject, val.transform.parent, false);
			_totalCounter.transform.Translate(0f, 1f, 0f);
			Vector3 localPosition = _totalCounter.transform.localPosition;
			_totalCounter.transform.localPosition = new Vector3(localPosition.x + 50f, -50f, localPosition.z);
			_textMesh = _totalCounter.GetComponentInChildren<TextMeshProUGUI>();
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/core/XUnity.Common.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using XUnity.Common.Constants;
using XUnity.Common.Extensions;
using XUnity.Common.Logging;
using XUnity.Common.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("XUnity.AutoTranslator.Plugin.Core")]
[assembly: AssemblyCompany("gravydevsupreme")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Common dependencies shared between XUnity Auto Translator and Resource Redirector.")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("XUnity.Common")]
[assembly: AssemblyTitle("XUnity.Common")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
namespace XUnity.Common.Utilities
{
	public static class ArrayHelper
	{
		public static T[] Null<T>()
		{
			return null;
		}
	}
	public static class CabHelper
	{
		private static string CreateRandomCab()
		{
			return "CAB-" + Guid.NewGuid().ToString("N");
		}

		public static void RandomizeCab(byte[] assetBundleData)
		{
			string @string = Encoding.ASCII.GetString(assetBundleData, 0, Math.Min(1024, assetBundleData.Length - 4));
			int num = @string.IndexOf("CAB-", StringComparison.Ordinal);
			if (num >= 0)
			{
				int num2 = @string.Substring(num).IndexOf('\0');
				if (num2 >= 0 && num2 <= 36)
				{
					string s = CreateRandomCab();
					Buffer.BlockCopy(Encoding.ASCII.GetBytes(s), 36 - num2, assetBundleData, num, num2);
				}
			}
		}

		public static void RandomizeCabWithAnyLength(byte[] assetBundleData)
		{
			FindAndReplaceCab("CAB-", 0, assetBundleData, 2048);
		}

		private static void FindAndReplaceCab(string ansiStringToStartWith, byte byteToEndWith, byte[] data, int maxIterations = -1)
		{
			int num = Math.Min(data.Length, maxIterations);
			if (num == -1)
			{
				num = data.Length;
			}
			int num2 = 0;
			int length = ansiStringToStartWith.Length;
			string text = Guid.NewGuid().ToString("N");
			int num3 = 0;
			for (int i = 0; i < num; i++)
			{
				char c = (char)data[i];
				if (num2 == length)
				{
					while (data[i] != byteToEndWith && i < num)
					{
						if (num3 >= text.Length)
						{
							num3 = 0;
							text = Guid.NewGuid().ToString("N");
						}
						data[i++] = (byte)text[num3++];
					}
					break;
				}
				num2 = ((c == ansiStringToStartWith[num2]) ? (num2 + 1) : 0);
			}
		}
	}
	internal static class CecilFastReflectionHelper
	{
		private static readonly Type[] DynamicMethodDelegateArgs = new Type[2]
		{
			typeof(object),
			typeof(object[])
		};

		public static FastReflectionDelegate CreateFastDelegate(MethodBase method, bool directBoxValueAccess, bool forceNonVirtcall)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + method.DeclaringType.FullName + "." + method.Name + ">", typeof(object), DynamicMethodDelegateArgs);
			ILProcessor iLProcessor = val.GetILProcessor();
			ParameterInfo[] parameters = method.GetParameters();
			bool flag = true;
			if (!method.IsStatic)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
				if (method.DeclaringType.IsValueType)
				{
					Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, method.DeclaringType);
				}
			}
			for (int i = 0; i < parameters.Length; i++)
			{
				Type type = parameters[i].ParameterType;
				bool isByRef = type.IsByRef;
				if (isByRef)
				{
					type = type.GetElementType();
				}
				bool isValueType = type.IsValueType;
				if (isByRef && isValueType && !directBoxValueAccess)
				{
					iLProcessor.Emit(OpCodes.Ldarg_1);
					iLProcessor.Emit(OpCodes.Ldc_I4, i);
				}
				iLProcessor.Emit(OpCodes.Ldarg_1);
				iLProcessor.Emit(OpCodes.Ldc_I4, i);
				if (isByRef && !isValueType)
				{
					Extensions.Emit(iLProcessor, OpCodes.Ldelema, typeof(object));
					continue;
				}
				iLProcessor.Emit(OpCodes.Ldelem_Ref);
				if (!isValueType)
				{
					continue;
				}
				if (!isByRef || !directBoxValueAccess)
				{
					Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, type);
					if (isByRef)
					{
						Extensions.Emit(iLProcessor, OpCodes.Box, type);
						iLProcessor.Emit(OpCodes.Dup);
						Extensions.Emit(iLProcessor, OpCodes.Unbox, type);
						if (flag)
						{
							flag = false;
							val.Definition.Body.Variables.Add(new VariableDefinition((TypeReference)new PinnedType((TypeReference)new PointerType(((MemberReference)val.Definition).Module.TypeSystem.Void))));
						}
						iLProcessor.Emit(OpCodes.Stloc_0);
						iLProcessor.Emit(OpCodes.Stelem_Ref);
						iLProcessor.Emit(OpCodes.Ldloc_0);
					}
				}
				else
				{
					Extensions.Emit(iLProcessor, OpCodes.Unbox, type);
				}
			}
			if (method.IsConstructor)
			{
				Extensions.Emit(iLProcessor, OpCodes.Newobj, (MethodBase)(method as ConstructorInfo));
			}
			else if (method.IsFinal || !method.IsVirtual || forceNonVirtcall)
			{
				Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)(method as MethodInfo));
			}
			else
			{
				Extensions.Emit(iLProcessor, OpCodes.Callvirt, (MethodBase)(method as MethodInfo));
			}
			Type type2 = (method.IsConstructor ? method.DeclaringType : (method as MethodInfo).ReturnType);
			if ((object)type2 != typeof(void))
			{
				if (type2.IsValueType)
				{
					Extensions.Emit(iLProcessor, OpCodes.Box, type2);
				}
			}
			else
			{
				iLProcessor.Emit(OpCodes.Ldnull);
			}
			iLProcessor.Emit(OpCodes.Ret);
			return (FastReflectionDelegate)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(FastReflectionDelegate));
		}

		public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new ArgumentException("FieldInfo type does not match return type.");
			}
			if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T))))
			{
				throw new MissingFieldException(typeof(T).Name, fieldInfo.Name);
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + typeof(T).FullName + ".Get_" + fieldInfo.Name + ">", typeof(F), new Type[1] { typeof(T) });
			ILProcessor iLProcessor = val.GetILProcessor();
			if (!fieldInfo.IsStatic)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
				Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.DeclaringType);
			}
			Extensions.Emit(iLProcessor, fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, fieldInfo);
			if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType)
			{
				Extensions.Emit(iLProcessor, OpCodes.Box, fieldInfo.FieldType);
			}
			iLProcessor.Emit(OpCodes.Ret);
			return (Func<T, F>)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(Func<T, F>));
		}

		public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new ArgumentException("FieldInfo type does not match argument type.");
			}
			if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T))))
			{
				throw new MissingFieldException(typeof(T).Name, fieldInfo.Name);
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition("FastReflection<" + typeof(T).FullName + ".Set_" + fieldInfo.Name + ">", (Type)null, new Type[2]
			{
				typeof(T),
				typeof(F)
			});
			ILProcessor iLProcessor = val.GetILProcessor();
			if (!fieldInfo.IsStatic)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
				Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.DeclaringType);
			}
			iLProcessor.Emit(OpCodes.Ldarg_1);
			if ((object)fieldInfo.FieldType != typeof(F))
			{
				if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType)
				{
					if (fieldInfo.FieldType.IsValueType)
					{
						Extensions.Emit(iLProcessor, OpCodes.Unbox_Any, fieldInfo.FieldType);
					}
					else
					{
						Extensions.Emit(iLProcessor, OpCodes.Box, fieldInfo.FieldType);
					}
				}
				else
				{
					Extensions.Emit(iLProcessor, OpCodes.Castclass, fieldInfo.FieldType);
				}
			}
			Extensions.Emit(iLProcessor, fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo);
			iLProcessor.Emit(OpCodes.Ret);
			return (Action<T, F>)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(Action<T, F>));
		}
	}
	public static class CustomFastReflectionHelper
	{
		private struct FastReflectionDelegateKey
		{
			public MethodBase Method { get; }

			public bool DirectBoxValueAccess { get; }

			public bool ForceNonVirtCall { get; }

			public FastReflectionDelegateKey(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall)
			{
				Method = method;
				DirectBoxValueAccess = directBoxValueAccess;
				ForceNonVirtCall = forceNonVirtCall;
			}

			public override bool Equals(object obj)
			{
				if (obj is FastReflectionDelegateKey fastReflectionDelegateKey && EqualityComparer<MethodBase>.Default.Equals(Method, fastReflectionDelegateKey.Method) && DirectBoxValueAccess == fastReflectionDelegateKey.DirectBoxValueAccess)
				{
					return ForceNonVirtCall == fastReflectionDelegateKey.ForceNonVirtCall;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return ((1017116076 * -1521134295 + EqualityComparer<MethodBase>.Default.GetHashCode(Method)) * -1521134295 + DirectBoxValueAccess.GetHashCode()) * -1521134295 + ForceNonVirtCall.GetHashCode();
			}
		}

		private static readonly Dictionary<FastReflectionDelegateKey, FastReflectionDelegate> MethodCache = new Dictionary<FastReflectionDelegateKey, FastReflectionDelegate>();

		public static FastReflectionDelegate CreateFastDelegate(this MethodBase method, bool directBoxValueAccess = true, bool forceNonVirtCall = false)
		{
			FastReflectionDelegateKey key = new FastReflectionDelegateKey(method, directBoxValueAccess, forceNonVirtCall);
			if (MethodCache.TryGetValue(key, out var value))
			{
				return value;
			}
			value = (((object)ClrTypes.DynamicMethodDefinition == null) ? GetFastDelegateForSRE(method, directBoxValueAccess, forceNonVirtCall) : GetFastDelegateForCecil(method, directBoxValueAccess, forceNonVirtCall));
			MethodCache.Add(key, value);
			return value;
		}

		public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo)
		{
			if ((object)ClrTypes.DynamicMethodDefinition != null)
			{
				return CreateFastFieldGetterForCecil<T, F>(fieldInfo);
			}
			return CreateFastFieldGetterForSRE<T, F>(fieldInfo);
		}

		public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo)
		{
			if ((object)ClrTypes.DynamicMethodDefinition != null)
			{
				return CreateFastFieldSetterForCecil<T, F>(fieldInfo);
			}
			return CreateFastFieldSetterForSRE<T, F>(fieldInfo);
		}

		private static FastReflectionDelegate GetFastDelegateForCecil(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall)
		{
			try
			{
				return CecilFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall);
			}
			catch (Exception e)
			{
				try
				{
					XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit...");
					return ReflectionEmitFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall);
				}
				catch (Exception e2)
				{
					XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
					return (object target, object[] args) => method.Invoke(target, args);
				}
			}
		}

		private static Func<T, F> CreateFastFieldGetterForCecil<T, F>(FieldInfo fieldInfo)
		{
			try
			{
				return CecilFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo);
			}
			catch (Exception e)
			{
				try
				{
					XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit...");
					return ReflectionEmitFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo);
				}
				catch (Exception e2)
				{
					XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
					return (T target) => (F)fieldInfo.GetValue(target);
				}
			}
		}

		private static Action<T, F> CreateFastFieldSetterForCecil<T, F>(FieldInfo fieldInfo)
		{
			try
			{
				return CecilFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo);
			}
			catch (Exception e)
			{
				try
				{
					XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with cecil. Retrying with reflection emit...");
					return ReflectionEmitFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo);
				}
				catch (Exception e2)
				{
					XuaLogger.Common.Warn(e2, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
					return delegate(T target, F value)
					{
						fieldInfo.SetValue(target, value);
					};
				}
			}
		}

		private static FastReflectionDelegate GetFastDelegateForSRE(MethodBase method, bool directBoxValueAccess, bool forceNonVirtCall)
		{
			try
			{
				return ReflectionEmitFastReflectionHelper.CreateFastDelegate(method, directBoxValueAccess, forceNonVirtCall);
			}
			catch (Exception e)
			{
				XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
				return (object target, object[] args) => method.Invoke(target, args);
			}
		}

		private static Func<T, F> CreateFastFieldGetterForSRE<T, F>(FieldInfo fieldInfo)
		{
			try
			{
				return ReflectionEmitFastReflectionHelper.CreateFastFieldGetter<T, F>(fieldInfo);
			}
			catch (Exception e)
			{
				XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
				return (T target) => (F)fieldInfo.GetValue(target);
			}
		}

		private static Action<T, F> CreateFastFieldSetterForSRE<T, F>(FieldInfo fieldInfo)
		{
			try
			{
				return ReflectionEmitFastReflectionHelper.CreateFastFieldSetter<T, F>(fieldInfo);
			}
			catch (Exception e)
			{
				XuaLogger.Common.Warn(e, "Failed creating fast reflection delegate through with reflection emit. Falling back to standard reflection...");
				return delegate(T target, F value)
				{
					fieldInfo.SetValue(target, value);
				};
			}
		}
	}
	public static class DiacriticHelper
	{
		public static string RemoveAllDiacritics(this string input)
		{
			return new string((from c in input.SafeNormalize(NormalizationForm.FormD)
				where CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark
				select c).ToArray()).SafeNormalize();
		}

		private static string SafeNormalize(this string input, NormalizationForm normalizationForm = NormalizationForm.FormC)
		{
			return ReplaceNonCharacters(input, '?').Normalize(normalizationForm);
		}

		private static string ReplaceNonCharacters(string input, char replacement)
		{
			StringBuilder stringBuilder = new StringBuilder(input.Length);
			for (int i = 0; i < input.Length; i++)
			{
				if (char.IsSurrogatePair(input, i))
				{
					int num = char.ConvertToUtf32(input, i);
					i++;
					if (IsValidCodePoint(num))
					{
						stringBuilder.Append(char.ConvertFromUtf32(num));
					}
					else
					{
						stringBuilder.Append(replacement);
					}
				}
				else
				{
					char c = input[i];
					if (IsValidCodePoint(c))
					{
						stringBuilder.Append(c);
					}
					else
					{
						stringBuilder.Append(replacement);
					}
				}
			}
			return stringBuilder.ToString();
		}

		private static bool IsValidCodePoint(int point)
		{
			if (point >= 64976)
			{
				if (point >= 65008 && (point & 0xFFFF) != 65535 && (point & 0xFFFE) != 65534)
				{
					return point <= 1114111;
				}
				return false;
			}
			return true;
		}
	}
	public static class ExpressionHelper
	{
		public static Delegate CreateTypedFastInvoke(MethodBase method)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			return CreateTypedFastInvokeUnchecked(method);
		}

		public static Delegate CreateTypedFastInvokeUnchecked(MethodBase method)
		{
			if ((object)method == null)
			{
				return null;
			}
			if (method.IsGenericMethod)
			{
				throw new ArgumentException("The provided method must not be generic.", "method");
			}
			if (method is MethodInfo methodInfo)
			{
				Expression[] arguments;
				if (method.IsStatic)
				{
					ParameterExpression[] array = (from p in methodInfo.GetParameters()
						select Expression.Parameter(p.ParameterType, p.Name)).ToArray();
					arguments = array;
					return Expression.Lambda(Expression.Call(null, methodInfo, arguments), array).Compile();
				}
				List<ParameterExpression> list = (from p in methodInfo.GetParameters()
					select Expression.Parameter(p.ParameterType, p.Name)).ToList();
				list.Insert(0, Expression.Parameter(methodInfo.DeclaringType, "instance"));
				ParameterExpression instance = list[0];
				arguments = list.Skip(1).ToArray();
				return Expression.Lambda(Expression.Call(instance, methodInfo, arguments), list.ToArray()).Compile();
			}
			if (method is ConstructorInfo constructorInfo)
			{
				ParameterExpression[] array2 = (from p in constructorInfo.GetParameters()
					select Expression.Parameter(p.ParameterType, p.Name)).ToArray();
				Expression[] arguments = array2;
				return Expression.Lambda(Expression.New(constructorInfo, arguments), array2).Compile();
			}
			throw new ArgumentException("method", "This method only supports MethodInfo and ConstructorInfo.");
		}
	}
	public static class ExtensionDataHelper
	{
		private static readonly object Sync;

		private static readonly WeakDictionary<object, object> WeakDynamicFields;

		public static int WeakReferenceCount
		{
			get
			{
				lock (Sync)
				{
					return WeakDynamicFields.Count;
				}
			}
		}

		static ExtensionDataHelper()
		{
			Sync = new object();
			WeakDynamicFields = new WeakDictionary<object, object>();
			MaintenanceHelper.AddMaintenanceFunction(Cull, 12);
		}

		public static void SetExtensionData<T>(this object obj, T t)
		{
			lock (Sync)
			{
				if (WeakDynamicFields.TryGetValue(obj, out var value))
				{
					if (value is Dictionary<Type, object> dictionary)
					{
						dictionary[typeof(T)] = t;
						return;
					}
					Dictionary<Type, object> dictionary2 = new Dictionary<Type, object>();
					dictionary2.Add(value.GetType(), value);
					dictionary2[typeof(T)] = t;
					WeakDynamicFields[obj] = dictionary2;
				}
				else
				{
					WeakDynamicFields[obj] = t;
				}
			}
		}

		public static T GetOrCreateExtensionData<T>(this object obj) where T : new()
		{
			if (obj == null)
			{
				return default(T);
			}
			lock (Sync)
			{
				if (WeakDynamicFields.TryGetValue(obj, out var value))
				{
					if (value is Dictionary<Type, object> dictionary)
					{
						if (dictionary.TryGetValue(typeof(T), out value))
						{
							return (T)value;
						}
						T val = new T();
						dictionary[typeof(T)] = val;
						return val;
					}
					if (!(value is T result))
					{
						Dictionary<Type, object> dictionary2 = new Dictionary<Type, object>();
						dictionary2.Add(value.GetType(), value);
						T val2 = new T();
						dictionary2[typeof(T)] = val2;
						WeakDynamicFields[obj] = dictionary2;
						return val2;
					}
					return result;
				}
				T val3 = new T();
				WeakDynamicFields[obj] = val3;
				return val3;
			}
		}

		public static T GetExtensionData<T>(this object obj)
		{
			if (obj == null)
			{
				return default(T);
			}
			lock (Sync)
			{
				if (WeakDynamicFields.TryGetValue(obj, out var value))
				{
					if (value is Dictionary<Type, object> dictionary && dictionary.TryGetValue(typeof(T), out value))
					{
						if (!(value is T result))
						{
							return default(T);
						}
						return result;
					}
					if (!(value is T result2))
					{
						return default(T);
					}
					return result2;
				}
			}
			return default(T);
		}

		public static void Cull()
		{
			lock (Sync)
			{
				WeakDynamicFields.RemoveCollectedEntries();
			}
		}

		public static List<KeyValuePair<object, object>> GetAllRegisteredObjects()
		{
			lock (Sync)
			{
				return IterateAllPairs().ToList();
			}
		}

		public static void Remove(object obj)
		{
			lock (Sync)
			{
				WeakDynamicFields.Remove(obj);
			}
		}

		private static IEnumerable<KeyValuePair<object, object>> IterateAllPairs()
		{
			foreach (KeyValuePair<object, object> kvp in WeakDynamicFields)
			{
				if (kvp.Value is Dictionary<Type, object> dictionary)
				{
					foreach (KeyValuePair<Type, object> item in dictionary)
					{
						yield return new KeyValuePair<object, object>(kvp.Key, item.Value);
					}
				}
				else
				{
					yield return kvp;
				}
			}
		}
	}
	public delegate object FastReflectionDelegate(object target, params object[] args);
	public static class HookingHelper
	{
		private static readonly MethodInfo PatchMethod12;

		private static readonly MethodInfo PatchMethod20;

		private static readonly object Harmony;

		private static bool _loggedHarmonyError;

		static HookingHelper()
		{
			PatchMethod12 = ClrTypes.HarmonyInstance?.GetMethod("Patch", new Type[4]
			{
				ClrTypes.MethodBase,
				ClrTypes.HarmonyMethod,
				ClrTypes.HarmonyMethod,
				ClrTypes.HarmonyMethod
			});
			PatchMethod20 = ClrTypes.Harmony?.GetMethod("Patch", new Type[5]
			{
				ClrTypes.MethodBase,
				ClrTypes.HarmonyMethod,
				ClrTypes.HarmonyMethod,
				ClrTypes.HarmonyMethod,
				ClrTypes.HarmonyMethod
			});
			_loggedHarmonyError = false;
			try
			{
				if ((object)ClrTypes.HarmonyInstance != null)
				{
					Harmony = ClrTypes.HarmonyInstance.GetMethod("Create", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { "xunity.common.hookinghelper" });
				}
				else if ((object)ClrTypes.Harmony != null)
				{
					Harmony = ClrTypes.Harmony.GetConstructor(new Type[1] { typeof(string) }).Invoke(new object[1] { "xunity.common.hookinghelper" });
				}
				else
				{
					XuaLogger.Common.Error("An unexpected exception occurred during harmony initialization, likely caused by unknown Harmony version. Harmony hooks will be unavailable!");
				}
			}
			catch (Exception e)
			{
				XuaLogger.Common.Error(e, "An unexpected exception occurred during harmony initialization. Harmony hooks will be unavailable!");
			}
		}

		public static void PatchAll(IEnumerable<Type> types, bool forceExternHooks)
		{
			foreach (Type type in types)
			{
				PatchType(type, forceExternHooks);
			}
		}

		public static void PatchAll(IEnumerable<Type[]> types, bool forceMonoModHooks)
		{
			foreach (Type[] type in types)
			{
				for (int i = 0; i < type.Length && !PatchType(type[i], forceMonoModHooks); i++)
				{
				}
			}
		}

		public static bool PatchType(Type type, bool forceExternHooks)
		{
			MethodBase methodBase = null;
			IntPtr intPtr = IntPtr.Zero;
			try
			{
				if (Harmony == null && !_loggedHarmonyError)
				{
					_loggedHarmonyError = true;
					XuaLogger.Common.Warn("Harmony is not loaded or could not be initialized. Using fallback hooks instead.");
				}
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
				MethodInfo method = type.GetMethod("Prepare", bindingAttr);
				if ((object)method == null || (bool)method.Invoke(null, new object[1] { Harmony }))
				{
					try
					{
						methodBase = (MethodBase)(type.GetMethod("TargetMethod", bindingAttr)?.Invoke(null, new object[1] { Harmony }));
					}
					catch
					{
					}
					try
					{
						intPtr = ((IntPtr?)type.GetMethod("TargetMethodPointer", bindingAttr)?.Invoke(null, null)) ?? IntPtr.Zero;
					}
					catch
					{
					}
					if ((object)methodBase == null && intPtr == IntPtr.Zero)
					{
						if ((object)methodBase != null)
						{
							XuaLogger.Common.Warn("Could not hook '" + methodBase.DeclaringType.FullName + "." + methodBase.Name + "'. Likely due differences between different versions of the engine or text framework.");
						}
						else
						{
							XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework.");
						}
						return false;
					}
					MethodInfo method2 = type.GetMethod("Prefix", bindingAttr);
					MethodInfo method3 = type.GetMethod("Postfix", bindingAttr);
					MethodInfo method4 = type.GetMethod("Finalizer", bindingAttr);
					if ((object)methodBase == null || forceExternHooks || Harmony == null || ((object)method2 == null && (object)method3 == null && (object)method4 == null))
					{
						return PatchWithExternHooks(type, methodBase, intPtr, forced: true);
					}
					if ((object)methodBase != null)
					{
						try
						{
							int? priority = type.GetCustomAttributes(typeof(HookingHelperPriorityAttribute), inherit: false).OfType<HookingHelperPriorityAttribute>().FirstOrDefault()?.priority;
							object obj3 = (((object)method2 != null) ? CreateHarmonyMethod(method2, priority) : null);
							object obj4 = (((object)method3 != null) ? CreateHarmonyMethod(method3, priority) : null);
							object obj5 = (((object)method4 != null) ? CreateHarmonyMethod(method4, priority) : null);
							if ((object)PatchMethod12 != null)
							{
								PatchMethod12.Invoke(Harmony, new object[4] { methodBase, obj3, obj4, null });
							}
							else
							{
								PatchMethod20.Invoke(Harmony, new object[5] { methodBase, obj3, obj4, null, obj5 });
							}
							XuaLogger.Common.Debug("Hooked " + methodBase.DeclaringType.FullName + "." + methodBase.Name + " through Harmony hooks.");
							return true;
						}
						catch (Exception e) when (((Func<bool>)delegate
						{
							// Could not convert BlockContainer to single expression
							System.Runtime.CompilerServices.Unsafe.SkipInit(out int num);
							if (e.FirstInnerExceptionOfType<PlatformNotSupportedException>() == null)
							{
								ArgumentException ex = e.FirstInnerExceptionOfType<ArgumentException>();
								num = ((ex != null && ex.Message?.Contains("no body") == true) ? 1 : 0);
							}
							else
							{
								num = 1;
							}
							return num != 0;
						}).Invoke())
						{
							return PatchWithExternHooks(type, methodBase, intPtr, forced: false);
						}
					}
					XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework.");
				}
			}
			catch (Exception e2)
			{
				if ((object)methodBase != null)
				{
					XuaLogger.Common.Warn(e2, "An error occurred while patching property/method '" + methodBase.DeclaringType.FullName + "." + methodBase.Name + "'. Failing hook: '" + type.Name + "'.");
				}
				else
				{
					XuaLogger.Common.Warn(e2, "An error occurred while patching property/method. Failing hook: '" + type.Name + "'.");
				}
			}
			return false;
		}

		private static bool PatchWithExternHooks(Type type, MethodBase original, IntPtr originalPtr, bool forced)
		{
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			if ((object)ClrTypes.Imports != null)
			{
				if (originalPtr == IntPtr.Zero)
				{
					XuaLogger.Common.Warn("Could not hook '" + type.Name + "'. Likely due differences between different versions of the engine or text framework.");
					return false;
				}
				IntPtr? intPtr = type.GetMethod("ML_Detour", bindingAttr)?.MethodHandle.GetFunctionPointer();
				if (intPtr.HasValue && intPtr.Value != IntPtr.Zero)
				{
					ClrTypes.Imports.GetMethod("Hook", bindingAttr).Invoke(null, new object[2] { originalPtr, intPtr.Value });
					XuaLogger.Common.Debug("Hooked " + type.Name + " through MelonMod Imports.Hook method.");
					return true;
				}
				XuaLogger.Common.Warn("Could not hook '" + type.Name + "' because no detour method was found.");
			}
			else
			{
				if ((object)original == null)
				{
					XuaLogger.Common.Warn("Cannot hook '" + type.Name + "'. Could not locate the original method. Failing hook: '" + type.Name + "'.");
					return false;
				}
				if ((object)ClrTypes.Hook == null || (object)ClrTypes.NativeDetour == null)
				{
					XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. MonoMod hooks is not supported in this runtime as MonoMod is not loaded. Failing hook: '" + type.Name + "'.");
					return false;
				}
				object obj = type.GetMethod("Get_MM_Detour", bindingAttr)?.Invoke(null, null) ?? type.GetMethod("MM_Detour", bindingAttr);
				if (obj != null)
				{
					string text = "(managed)";
					object obj2;
					try
					{
						obj2 = ClrTypes.Hook.GetConstructor(new Type[2]
						{
							typeof(MethodBase),
							typeof(MethodInfo)
						}).Invoke(new object[2] { original, obj });
						obj2.GetType().GetMethod("Apply").Invoke(obj2, null);
					}
					catch (Exception e) when (((Func<bool>)delegate
					{
						// Could not convert BlockContainer to single expression
						System.Runtime.CompilerServices.Unsafe.SkipInit(out int num);
						if (e.FirstInnerExceptionOfType<NullReferenceException>() == null)
						{
							NotSupportedException ex = e.FirstInnerExceptionOfType<NotSupportedException>();
							num = ((ex != null && ex.Message?.Contains("Body-less") == true) ? 1 : 0);
						}
						else
						{
							num = 1;
						}
						return num != 0;
					}).Invoke())
					{
						text = "(native)";
						obj2 = ClrTypes.NativeDetour.GetConstructor(new Type[2]
						{
							typeof(MethodBase),
							typeof(MethodBase)
						}).Invoke(new object[2] { original, obj });
						obj2.GetType().GetMethod("Apply").Invoke(obj2, null);
					}
					type.GetMethod("MM_Init", bindingAttr)?.Invoke(null, new object[1] { obj2 });
					if (forced)
					{
						XuaLogger.Common.Debug("Hooked " + original.DeclaringType.FullName + "." + original.Name + " through forced MonoMod hooks. " + text);
					}
					else
					{
						XuaLogger.Common.Debug("Hooked " + original.DeclaringType.FullName + "." + original.Name + " through MonoMod hooks. " + text);
					}
					return true;
				}
				if (forced)
				{
					XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. Harmony is not supported in this runtime and no alternate MonoMod hook has been implemented. Failing hook: '" + type.Name + "'.");
				}
				else
				{
					XuaLogger.Common.Warn("Cannot hook '" + original.DeclaringType.FullName + "." + original.Name + "'. Harmony is not supported in this runtime and no alternate MonoMod hook has been implemented. Failing hook: '" + type.Name + "'.");
				}
			}
			return false;
		}

		private static object CreateHarmonyMethod(MethodInfo method, int? priority)
		{
			object obj = ClrTypes.HarmonyMethod.GetConstructor(new Type[1] { typeof(MethodInfo) }).Invoke(new object[1] { method });
			if (priority.HasValue)
			{
				(ClrTypes.HarmonyMethod.GetField("priority", BindingFlags.Instance | BindingFlags.Public) ?? ClrTypes.HarmonyMethod.GetField("prioritiy", BindingFlags.Instance | BindingFlags.Public)).SetValue(obj, priority.Value);
			}
			return obj;
		}
	}
	public class HookingHelperPriorityAttribute : Attribute
	{
		public int priority;

		public HookingHelperPriorityAttribute(int priority)
		{
			this.priority = priority;
		}
	}
	public static class HookPriority
	{
		public const int Last = 0;

		public const int VeryLow = 100;

		public const int Low = 200;

		public const int LowerThanNormal = 300;

		public const int Normal = 400;

		public const int HigherThanNormal = 500;

		public const int High = 600;

		public const int VeryHigh = 700;

		public const int First = 800;
	}
	public static class ListExtensions
	{
		public static void BinarySearchInsert<T>(this List<T> items, T item) where T : IComparable<T>
		{
			int num = items.BinarySearch(item);
			if (num < 0)
			{
				items.Insert(~num, item);
			}
			else
			{
				items.Insert(num, item);
			}
		}
	}
	public static class MaintenanceHelper
	{
		private class ActionRegistration
		{
			public Action Action { get; }

			public int Filter { get; }

			public ActionRegistration(Action action, int filter)
			{
				Action = action;
				Filter = filter;
			}
		}

		private static readonly object Sync = new object();

		private static readonly List<ActionRegistration> RegisteredActions = new List<ActionRegistration>();

		private static bool _initialized;

		public static void AddMaintenanceFunction(Action action, int filter)
		{
			lock (Sync)
			{
				if (!_initialized)
				{
					_initialized = true;
					StartMaintenance();
				}
				ActionRegistration item = new ActionRegistration(action, filter);
				RegisteredActions.Add(item);
			}
		}

		private static void StartMaintenance()
		{
			Thread thread = new Thread(MaintenanceLoop);
			thread.IsBackground = true;
			thread.Start();
		}

		private static void MaintenanceLoop(object state)
		{
			int num = 0;
			while (true)
			{
				lock (Sync)
				{
					foreach (ActionRegistration registeredAction in RegisteredActions)
					{
						if (num % registeredAction.Filter == 0)
						{
							try
							{
								registeredAction.Action();
							}
							catch (Exception e)
							{
								XuaLogger.Common.Error(e, "An unexpected error occurred during maintenance.");
							}
						}
					}
				}
				num++;
				Thread.Sleep(5000);
			}
		}
	}
	public static class Paths
	{
		private static string _gameRoot;

		public static string GameRoot
		{
			get
			{
				return _gameRoot ?? GetAndSetGameRoot();
			}
			set
			{
				_gameRoot = value;
			}
		}

		public static void Initialize()
		{
			GetAndSetGameRoot();
		}

		private static string GetAndSetGameRoot()
		{
			return _gameRoot = new DirectoryInfo(Application.dataPath).Parent.FullName;
		}
	}
	public static class ReflectionCache
	{
		private struct MemberLookupKey
		{
			public Type Type { get; set; }

			public string MemberName { get; set; }

			public MemberLookupKey(Type type, string memberName)
			{
				Type = type;
				MemberName = memberName;
			}

			public override bool Equals(object obj)
			{
				if (obj is MemberLookupKey memberLookupKey)
				{
					if ((object)Type == memberLookupKey.Type)
					{
						return MemberName == memberLookupKey.MemberName;
					}
					return false;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return Type.GetHashCode() + MemberName.GetHashCode();
			}
		}

		private static Dictionary<MemberLookupKey, CachedMethod> Methods = new Dictionary<MemberLookupKey, CachedMethod>();

		private static Dictionary<MemberLookupKey, CachedProperty> Properties = new Dictionary<MemberLookupKey, CachedProperty>();

		private static Dictionary<MemberLookupKey, CachedField> Fields = new Dictionary<MemberLookupKey, CachedField>();

		public static CachedMethod CachedMethod(this Type type, string name)
		{
			return type.CachedMethod(name, (Type[])null);
		}

		public static CachedMethod CachedMethod(this Type type, string name, params Type[] types)
		{
			MemberLookupKey key = new MemberLookupKey(type, name);
			if (!Methods.TryGetValue(key, out var value))
			{
				Type type2 = type;
				MethodInfo methodInfo = null;
				while ((object)methodInfo == null && (object)type2 != null)
				{
					methodInfo = ((types != null && types.Length != 0) ? type2.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null) : type2.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
					type2 = type2.BaseType;
				}
				if ((object)methodInfo != null)
				{
					value = new CachedMethod(methodInfo);
				}
				Methods[key] = value;
			}
			return value;
		}

		public static CachedProperty CachedProperty(this Type type, string name)
		{
			MemberLookupKey key = new MemberLookupKey(type, name);
			if (!Properties.TryGetValue(key, out var value))
			{
				Type type2 = type;
				PropertyInfo propertyInfo = null;
				while ((object)propertyInfo == null && (object)type2 != null)
				{
					propertyInfo = type2.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					type2 = type2.BaseType;
				}
				if ((object)propertyInfo != null)
				{
					value = new CachedProperty(propertyInfo);
				}
				Properties[key] = value;
			}
			return value;
		}

		public static CachedField CachedField(this Type type, string name)
		{
			MemberLookupKey key = new MemberLookupKey(type, name);
			if (!Fields.TryGetValue(key, out var value))
			{
				Type type2 = type;
				FieldInfo fieldInfo = null;
				while ((object)fieldInfo == null && (object)type2 != null)
				{
					fieldInfo = type2.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					type2 = type2.BaseType;
				}
				if ((object)fieldInfo != null)
				{
					value = new CachedField(fieldInfo);
				}
				Fields[key] = value;
			}
			return value;
		}

		public static CachedField CachedFieldByIndex(this Type type, int index, Type fieldType, BindingFlags flags)
		{
			FieldInfo[] array = (from x in type.GetFields(flags)
				where (object)x.FieldType == fieldType
				select x).ToArray();
			if (index < array.Length)
			{
				return new CachedField(array[index]);
			}
			return null;
		}
	}
	public class CachedMethod
	{
		private static readonly object[] Args0 = new object[0];

		private static readonly object[] Args1 = new object[1];

		private static readonly object[] Args2 = new object[2];

		private FastReflectionDelegate _invoke;

		internal CachedMethod(MethodInfo method)
		{
			_invoke = method.CreateFastDelegate();
		}

		public object Invoke(object instance, object[] arguments)
		{
			return _invoke(instance, arguments);
		}

		public object Invoke(object instance)
		{
			return _invoke(instance, Args0);
		}

		public object Invoke(object instance, object arg1)
		{
			try
			{
				Args1[0] = arg1;
				return _invoke(instance, Args1);
			}
			finally
			{
				Args1[0] = null;
			}
		}

		public object Invoke(object instance, object arg1, object arg2)
		{
			try
			{
				Args2[0] = arg1;
				Args2[1] = arg2;
				return _invoke(instance, Args2);
			}
			finally
			{
				Args2[0] = null;
				Args2[1] = null;
			}
		}
	}
	public class CachedProperty
	{
		private static readonly object[] Args0 = new object[0];

		private static readonly object[] Args1 = new object[1];

		private FastReflectionDelegate _set;

		private FastReflectionDelegate _get;

		public Type PropertyType { get; }

		internal CachedProperty(PropertyInfo propertyInfo)
		{
			if (propertyInfo.CanRead)
			{
				_get = propertyInfo.GetGetMethod(nonPublic: true).CreateFastDelegate();
			}
			if (propertyInfo.CanWrite)
			{
				_set = propertyInfo.GetSetMethod(nonPublic: true).CreateFastDelegate();
			}
			PropertyType = propertyInfo.PropertyType;
		}

		public void Set(object instance, object[] arguments)
		{
			if (_set != null)
			{
				_set(instance, arguments);
			}
		}

		public void Set(object instance, object arg1)
		{
			if (_set == null)
			{
				return;
			}
			try
			{
				Args1[0] = arg1;
				_set(instance, Args1);
			}
			finally
			{
				Args1[0] = null;
			}
		}

		public object Get(object instance, object[] arguments)
		{
			if (_get == null)
			{
				return null;
			}
			return _get(instance, arguments);
		}

		public object Get(object instance)
		{
			if (_get == null)
			{
				return null;
			}
			return _get(instance, Args0);
		}
	}
	public class CachedField
	{
		private Func<object, object> _get;

		private Action<object, object> _set;

		public Type FieldType { get; }

		internal CachedField(FieldInfo fieldInfo)
		{
			_get = CustomFastReflectionHelper.CreateFastFieldGetter<object, object>(fieldInfo);
			_set = CustomFastReflectionHelper.CreateFastFieldSetter<object, object>(fieldInfo);
			FieldType = fieldInfo.FieldType;
		}

		public void Set(object instance, object value)
		{
			if (_set != null)
			{
				_set(instance, value);
			}
		}

		public object Get(object instance)
		{
			if (_get == null)
			{
				return null;
			}
			return _get(instance);
		}
	}
	internal static class ReflectionEmitFastReflectionHelper
	{
		private static readonly Type[] DynamicMethodDelegateArgs = new Type[2]
		{
			typeof(object),
			typeof(object[])
		};

		public static FastReflectionDelegate CreateFastDelegate(MethodBase method, bool directBoxValueAccess, bool forceNonVirtcall)
		{
			DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + method.DeclaringType.FullName + "." + method.Name + ">", typeof(object), DynamicMethodDelegateArgs, method.DeclaringType.Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			ParameterInfo[] parameters = method.GetParameters();
			bool flag = true;
			if (!method.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				if (method.DeclaringType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, method.DeclaringType);
				}
			}
			for (int i = 0; i < parameters.Length; i++)
			{
				Type type = parameters[i].ParameterType;
				bool isByRef = type.IsByRef;
				if (isByRef)
				{
					type = type.GetElementType();
				}
				bool isValueType = type.IsValueType;
				if (isByRef && isValueType && !directBoxValueAccess)
				{
					iLGenerator.Emit(OpCodes.Ldarg_1);
					iLGenerator.Emit(OpCodes.Ldc_I4, i);
				}
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Ldc_I4, i);
				if (isByRef && !isValueType)
				{
					iLGenerator.Emit(OpCodes.Ldelema, typeof(object));
					continue;
				}
				iLGenerator.Emit(OpCodes.Ldelem_Ref);
				if (!isValueType)
				{
					continue;
				}
				if (!isByRef || !directBoxValueAccess)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, type);
					if (isByRef)
					{
						iLGenerator.Emit(OpCodes.Box, type);
						iLGenerator.Emit(OpCodes.Dup);
						iLGenerator.Emit(OpCodes.Unbox, type);
						if (flag)
						{
							flag = false;
							throw new NotImplementedException("No idea how to implement this...");
						}
						iLGenerator.Emit(OpCodes.Stloc_0);
						iLGenerator.Emit(OpCodes.Stelem_Ref);
						iLGenerator.Emit(OpCodes.Ldloc_0);
					}
				}
				else
				{
					iLGenerator.Emit(OpCodes.Unbox, type);
				}
			}
			if (method.IsConstructor)
			{
				iLGenerator.Emit(OpCodes.Newobj, method as ConstructorInfo);
			}
			else if (method.IsFinal || !method.IsVirtual || forceNonVirtcall)
			{
				iLGenerator.Emit(OpCodes.Call, method as MethodInfo);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Callvirt, method as MethodInfo);
			}
			Type type2 = (method.IsConstructor ? method.DeclaringType : (method as MethodInfo).ReturnType);
			if ((object)type2 != typeof(void))
			{
				if (type2.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Box, type2);
				}
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldnull);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (FastReflectionDelegate)dynamicMethod.CreateDelegate(typeof(FastReflectionDelegate));
		}

		public static Func<T, F> CreateFastFieldGetter<T, F>(FieldInfo fieldInfo)
		{
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new ArgumentException("FieldInfo type does not match return type.");
			}
			if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T))))
			{
				throw new MissingFieldException(typeof(T).Name, fieldInfo.Name);
			}
			DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + typeof(T).FullName + ".Get_" + fieldInfo.Name + ">", typeof(F), new Type[1] { typeof(T) }, fieldInfo.DeclaringType.Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (!fieldInfo.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType);
			}
			iLGenerator.Emit(fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, fieldInfo);
			if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<T, F>)dynamicMethod.CreateDelegate(typeof(Func<T, F>));
		}

		public static Action<T, F> CreateFastFieldSetter<T, F>(FieldInfo fieldInfo)
		{
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!typeof(F).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new ArgumentException("FieldInfo type does not match argument type.");
			}
			if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T))))
			{
				throw new MissingFieldException(typeof(T).Name, fieldInfo.Name);
			}
			DynamicMethod dynamicMethod = new DynamicMethod("FastReflection<" + typeof(T).FullName + ".Set_" + fieldInfo.Name + ">", null, new Type[2]
			{
				typeof(T),
				typeof(F)
			}, fieldInfo.DeclaringType.Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (!fieldInfo.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType);
			}
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if ((object)fieldInfo.FieldType != typeof(F))
			{
				if (fieldInfo.FieldType.IsValueType != typeof(F).IsValueType)
				{
					if (fieldInfo.FieldType.IsValueType)
					{
						iLGenerator.Emit(OpCodes.Unbox, fieldInfo.FieldType);
					}
					else
					{
						iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
					}
				}
				else
				{
					iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType);
				}
			}
			iLGenerator.Emit(fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<T, F>)dynamicMethod.CreateDelegate(typeof(Action<T, F>));
		}
	}
	public static class TimeHelper
	{
		public static float realtimeSinceStartup => Time.realtimeSinceStartup;
	}
	public class UnityObjectReferenceComparer : IEqualityComparer<object>
	{
		public static readonly UnityObjectReferenceComparer Default = new UnityObjectReferenceComparer();

		public new bool Equals(object x, object y)
		{
			return x == y;
		}

		public int GetHashCode(object obj)
		{
			return obj.GetHashCode();
		}
	}
	public class WeakReference<T> : WeakReference where T : class
	{
		public new T Target => (T)base.Target;

		public static WeakReference<T> Create(T target)
		{
			if (target == null)
			{
				return WeakNullReference<T>.Singleton;
			}
			return new WeakReference<T>(target);
		}

		protected WeakReference(T target)
			: base(target, trackResurrection: false)
		{
		}
	}
	internal class WeakNullReference<T> : WeakReference<T> where T : class
	{
		public static readonly WeakNullReference<T> Singleton = new WeakNullReference<T>();

		public override bool IsAlive => true;

		private WeakNullReference()
			: base((T)null)
		{
		}
	}
	internal sealed class WeakKeyReference<T> : WeakReference<T> where T : class
	{
		public readonly int HashCode;

		public WeakKeyReference(T key, WeakKeyComparer<T> comparer)
			: base(key)
		{
			HashCode = comparer.GetHashCode(key);
		}
	}
	internal sealed class WeakKeyComparer<T> : IEqualityComparer<object> where T : class
	{
		private IEqualityComparer<T> comparer;

		internal WeakKeyComparer(IEqualityComparer<T> comparer)
		{
			if (comparer == null)
			{
				comparer = EqualityComparer<T>.Default;
			}
			this.comparer = comparer;
		}

		public int GetHashCode(object obj)
		{
			if (obj is WeakKeyReference<T> weakKeyReference)
			{
				return weakKeyReference.HashCode;
			}
			return comparer.GetHashCode((T)obj);
		}

		public new bool Equals(object x, object y)
		{
			bool isDead;
			T target = GetTarget(x, out isDead);
			bool isDead2;
			T target2 = GetTarget(y, out isDead2);
			if (isDead)
			{
				if (!isDead2)
				{
					return false;
				}
				return x == y;
			}
			if (isDead2)
			{
				return false;
			}
			return comparer.Equals(target, target2);
		}

		private static T GetTarget(object obj, out bool isDead)
		{
			T result;
			if (obj is WeakKeyReference<T> weakKeyReference)
			{
				result = weakKeyReference.Target;
				isDead = !weakKeyReference.IsAlive;
			}
			else
			{
				result = (T)obj;
				isDead = false;
			}
			return result;
		}
	}
	public sealed class WeakDictionary<TKey, TValue> : BaseDictionary<TKey, TValue> where TKey : class
	{
		private Dictionary<object, TValue> dictionary;

		private WeakKeyComparer<TKey> comparer;

		public override int Count => dictionary.Count;

		public WeakDictionary()
			: this(0, (IEqualityComparer<TKey>)null)
		{
		}

		public WeakDictionary(int capacity)
			: this(capacity, (IEqualityComparer<TKey>)null)
		{
		}

		public WeakDictionary(IEqualityComparer<TKey> comparer)
			: this(0, comparer)
		{
		}

		public WeakDictionary(int capacity, IEqualityComparer<TKey> comparer)
		{
			this.comparer = new WeakKeyComparer<TKey>(comparer);
			dictionary = new Dictionary<object, TValue>(capacity, this.comparer);
		}

		public override void Add(TKey key, TValue value)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			WeakReference<TKey> key2 = new WeakKeyReference<TKey>(key, comparer);
			dictionary.Add(key2, value);
		}

		public override bool ContainsKey(TKey key)
		{
			return dictionary.ContainsKey(key);
		}

		public override bool Remove(TKey key)
		{
			return dictionary.Remove(key);
		}

		public override bool TryGetValue(TKey key, out TValue value)
		{
			if (dictionary.TryGetValue(key, out value))
			{
				return true;
			}
			value = default(TValue);
			return false;
		}

		protected override void SetValue(TKey key, TValue value)
		{
			WeakReference<TKey> key2 = new WeakKeyReference<TKey>(key, comparer);
			dictionary[key2] = value;
		}

		public override void Clear()
		{
			dictionary.Clear();
		}

		public override IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
		{
			foreach (KeyValuePair<object, TValue> item in dictionary)
			{
				WeakReference<TKey> obj = (WeakReference<TKey>)item.Key;
				TValue value = item.Value;
				TKey target = obj.Target;
				if (obj.IsAlive)
				{
					yield return new KeyValuePair<TKey, TValue>(target, value);
				}
			}
		}

		public void RemoveCollectedEntries()
		{
			List<object> list = null;
			foreach (KeyValuePair<object, TValue> item in dictionary)
			{
				WeakReference<TKey> weakReference = (WeakReference<TKey>)item.Key;
				if (!weakReference.IsAlive)
				{
					if (list == null)
					{
						list = new List<object>();
					}
					list.Add(weakReference);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (object item2 in list)
			{
				dictionary.Remove(item2);
			}
		}
	}
	[DebuggerDisplay("Count = {Count}")]
	[DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")]
	public abstract class BaseDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
	{
		private abstract class Collection<T> : ICollection<T>, IEnumerable<T>, IEnumerable
		{
			protected readonly IDictionary<TKey, TValue> dictionary;

			public int Count => dictionary.Count;

			public bool IsReadOnly => true;

			protected Collection(IDictionary<TKey, TValue> dictionary)
			{
				this.dictionary = dictionary;
			}

			public void CopyTo(T[] array, int arrayIndex)
			{
				BaseDictionary<TKey, TValue>.Copy((ICollection<T>)this, array, arrayIndex);
			}

			public virtual bool Contains(T item)
			{
				using (IEnumerator<T> enumerator = GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						T current = enumerator.Current;
						if (EqualityComparer<T>.Default.Equals(current, item))
						{
							return true;
						}
					}
				}
				return false;
			}

			public IEnumerator<T> GetEnumerator()
			{
				foreach (KeyValuePair<TKey, TValue> item in dictionary)
				{
					yield return GetItem(item);
				}
			}

			protected abstract T GetItem(KeyValuePair<TKey, TValue> pair);

			public bool Remove(T item)
			{
				throw new NotSupportedException("Collection is read-only.");
			}

			public void Add(T item)
			{
				throw new NotSupportedException("Collection is read-only.");
			}

			public void Clear()
			{
				throw new NotSupportedException("Collection is read-only.");
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return GetEnumerator();
			}
		}

		[DebuggerDisplay("Count = {Count}")]
		[DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryKeyCollectionDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")]
		private class KeyCollection : Collection<TKey>
		{
			public KeyCollection(IDictionary<TKey, TValue> dictionary)
				: base(dictionary)
			{
			}

			protected override TKey GetItem(KeyValuePair<TKey, TValue> pair)
			{
				return pair.Key;
			}

			public override bool Contains(TKey item)
			{
				return dictionary.ContainsKey(item);
			}
		}

		[DebuggerDisplay("Count = {Count}")]
		[DebuggerTypeProxy("System.Collections.Generic.Mscorlib_DictionaryValueCollectionDebugView`2,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089")]
		private class ValueCollection : Collection<TValue>
		{
			public ValueCollection(IDictionary<TKey, TValue> dictionary)
				: base(dictionary)
			{
			}

			protected override TValue GetItem(KeyValuePair<TKey, TValue> pair)
			{
				return pair.Value;
			}
		}

		private const string PREFIX = "System.Collections.Generic.Mscorlib_";

		private const string SUFFIX = ",mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089";

		private KeyCollection keys;

		private ValueCollection values;

		public abstract int Count { get; }

		public bool IsReadOnly => false;

		public ICollection<TKey> Keys
		{
			get
			{
				if (keys == null)
				{
					keys = new KeyCollection(this);
				}
				return keys;
			}
		}

		public ICollection<TValue> Values
		{
			get
			{
				if (values == null)
				{
					values = new ValueCollection(this);
				}
				return values;
			}
		}

		public TValue this[TKey key]
		{
			get
			{
				if (!TryGetValue(key, out var value))
				{
					throw new KeyNotFoundException();
				}
				return value;
			}
			set
			{
				SetValue(key, value);
			}
		}

		public abstract void Clear();

		public abstract void Add(TKey key, TValue value);

		public abstract bool ContainsKey(TKey key);

		public abstract bool Remove(TKey key);

		public abstract bool TryGetValue(TKey key, out TValue value);

		public abstract IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator();

		protected abstract void SetValue(TKey key, TValue value);

		public void Add(KeyValuePair<TKey, TValue> item)
		{
			Add(item.Key, item.Value);
		}

		public bool Contains(KeyValuePair<TKey, TValue> item)
		{
			if (!TryGetValue(item.Key, out var value))
			{
				return false;
			}
			return EqualityComparer<TValue>.Default.Equals(value, item.Value);
		}

		public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
		{
			Copy(this, array, arrayIndex);
		}

		public bool Remove(KeyValuePair<TKey, TValue> item)
		{
			if (!Contains(item))
			{
				return false;
			}
			return Remove(item.Key);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		private static void Copy<T>(ICollection<T> source, T[] array, int arrayIndex)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (arrayIndex < 0 || arrayIndex > array.Length)
			{
				throw new ArgumentOutOfRangeException("arrayIndex");
			}
			if (array.Length - arrayIndex < source.Count)
			{
				throw new ArgumentException("Destination array is not large enough. Check array.Length and arrayIndex.");
			}
			foreach (T item in source)
			{
				array[arrayIndex++] = item;
			}
		}
	}
}
namespace XUnity.Common.MonoMod
{
	public static class DetourExtensions
	{
		public static T GenerateTrampolineEx<T>(this object detour)
		{
			return (T)(from x in detour.GetType().GetMethods()
				where x.Name == "GenerateTrampoline" && x.IsGenericMethod
				select x).FirstOrDefault().MakeGenericMethod(typeof(T)).Invoke(detour, null);
		}
	}
}
namespace XUnity.Common.Logging
{
	internal class ConsoleLogger : XuaLogger
	{
		public ConsoleLogger(string source)
			: base(source)
		{
		}

		protected override void Log(LogLevel level, string message)
		{
			Console.WriteLine(GetDefaultPrefix(level) + " " + message);
		}
	}
	public enum LogLevel
	{
		Debug,
		Info,
		Warn,
		Error
	}
	internal class ModLoaderSpecificLogger : XuaLogger
	{
		public static class BepInExLogLevel
		{
			public const int None = 0;

			public const int Fatal = 1;

			public const int Error = 2;

			public const int Warning = 4;

			public const int Message = 8;

			public const int Info = 16;

			public const int Debug = 32;

			public const int All = 63;
		}

		private static Action<LogLevel, string> _logMethod;

		public ModLoaderSpecificLogger(string source)
			: base(source)
		{
			if (_logMethod != null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public;
			BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public;
			Type type = Type.GetType("BepInEx.Logging.LogLevel, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.LogLevel, BepInEx.Core", throwOnError: false);
			if ((object)type != null)
			{
				if ((object)(Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.ManualLogSource, BepInEx.Core", throwOnError: false)) != null)
				{
					MethodInfo method = (Type.GetType("BepInEx.Logging.Logger, BepInEx", throwOnError: false) ?? Type.GetType("BepInEx.Logging.Logger, BepInEx.Core", throwOnError: false)).GetMethod("CreateLogSource", bindingAttr, null, new Type[1] { typeof(string) }, null);
					object logInstance2 = method.Invoke(null, new object[1] { base.Source });
					MethodInfo method2 = logInstance2.GetType().GetMethod("Log", bindingAttr2, null, new Type[2]
					{
						type,
						typeof(object)
					}, null);
					FastReflectionDelegate log2 = method2.CreateFastDelegate();
					_logMethod = delegate(LogLevel level, string msg)
					{
						int num2 = Convert(level);
						log2(logInstance2, num2, msg);
					};
				}
				else
				{
					Type type2 = Type.GetType("BepInEx.Logger, BepInEx", throwOnError: false);
					object logInstance = type2.GetProperty("CurrentLogger", bindingAttr).GetValue(null, null);
					MethodInfo method3 = logInstance.GetType().GetMethod("Log", bindingAttr2, null, new Type[2]
					{
						type,
						typeof(object)
					}, null);
					FastReflectionDelegate log = method3.CreateFastDelegate();
					_logMethod = delegate(LogLevel level, string msg)
					{
						int num = Convert(level);
						log(logInstance, num, msg);
					};
				}
			}
			else
			{
				Type type3 = Type.GetType("MelonLoader.MelonLogger, MelonLoader.ModHandler", throwOnError: false);
				if ((object)type3 != null)
				{
					MethodInfo method4 = type3.GetMethod("Log", bindingAttr, null, new Type[2]
					{
						typeof(ConsoleColor),
						typeof(string)
					}, null);
					MethodInfo method5 = type3.GetMethod("Log", bindingAttr, null, new Type[1] { typeof(string) }, null);
					MethodInfo method6 = type3.GetMethod("LogWarning", bindingAttr, null, new Type[1] { typeof(string) }, null);
					MethodInfo method7 = type3.GetMethod("LogError", bindingAttr, null, new Type[1] { typeof(string) }, null);
					FastReflectionDelegate logDebug = method4.CreateFastDelegate();
					FastReflectionDelegate logInfo = method5.CreateFastDelegate();
					FastReflectionDelegate logWarning = method6.CreateFastDelegate();
					FastReflectionDelegate logError = method7.CreateFastDelegate();
					_logMethod = delegate(LogLevel level, string msg)
					{
						switch (level)
						{
						case LogLevel.Debug:
							logDebug(null, ConsoleColor.Gray, msg);
							break;
						case LogLevel.Info:
							logInfo(null, msg);
							break;
						case LogLevel.Warn:
							logWarning(null, msg);
							break;
						case LogLevel.Error:
							logError(null, msg);
							break;
						default:
							throw new ArgumentException("level");
						}
					};
				}
			}
			if (_logMethod != null)
			{
				return;
			}
			throw new Exception("Did not recognize any mod loader!");
		}

		protected override void Log(LogLevel level, string message)
		{
			_logMethod(level, message);
		}

		public static int Convert(LogLevel level)
		{
			return level switch
			{
				LogLevel.Debug => 32, 
				LogLevel.Info => 16, 
				LogLevel.Warn => 4, 
				LogLevel.Error => 2, 
				_ => 0, 
			};
		}
	}
	public abstract class XuaLogger
	{
		private static XuaLogger _default;

		private static XuaLogger _common;

		private static XuaLogger _resourceRedirector;

		public static XuaLogger AutoTranslator
		{
			get
			{
				if (_default == null)
				{
					_default = CreateLogger("XUnity.AutoTranslator");
				}
				return _default;
			}
			set
			{
				_default = value ?? throw new ArgumentNullException("value");
			}
		}

		public static XuaLogger Common
		{
			get
			{
				if (_common == null)
				{
					_common = CreateLogger("XUnity.Common");
				}
				return _common;
			}
			set
			{
				_common = value ?? throw new ArgumentNullException("value");
			}
		}

		public static XuaLogger ResourceRedirector
		{
			get
			{
				if (_resourceRedirector == null)
				{
					_resourceRedirector = CreateLogger("XUnity.ResourceRedirector");
				}
				return _resourceRedirector;
			}
			set
			{
				_resourceRedirector = value ?? throw new ArgumentNullException("value");
			}
		}

		public string Source { get; set; }

		internal static XuaLogger CreateLogger(string source)
		{
			try
			{
				return new ModLoaderSpecificLogger(source);
			}
			catch (Exception)
			{
				return new ConsoleLogger(source);
			}
		}

		public XuaLogger(string source)
		{
			Source = source;
		}

		public void Error(Exception e, string message)
		{
			Log(LogLevel.Error, message + Environment.NewLine + e);
		}

		public void Error(string message)
		{
			Log(LogLevel.Error, message);
		}

		public void Warn(Exception e, string message)
		{
			Log(LogLevel.Warn, message + Environment.NewLine + e);
		}

		public void Warn(string message)
		{
			Log(LogLevel.Warn, message);
		}

		public void Info(Exception e, string message)
		{
			Log(LogLevel.Info, message + Environment.NewLine + e);
		}

		public void Info(string message)
		{
			Log(LogLevel.Info, message);
		}

		public void Debug(Exception e, string message)
		{
			Log(LogLevel.Debug, message + Environment.NewLine + e);
		}

		public void Debug(string message)
		{
			Log(LogLevel.Debug, message);
		}

		protected abstract void Log(LogLevel level, string message);

		protected string GetDefaultPrefix(LogLevel level)
		{
			return level switch
			{
				LogLevel.Debug => "[DEBUG][" + Source + "]: ", 
				LogLevel.Info => "[INFO][" + Source + "]: ", 
				LogLevel.Warn => "[WARN][" + Source + "]: ", 
				LogLevel.Error => "[ERROR][" + Source + "]: ", 
				_ => "[UNKNOW][" + Source + "]: ", 
			};
		}
	}
}
namespace XUnity.Common.Harmony
{
	public static class AccessToolsShim
	{
		private static readonly BindingFlags All;

		private static readonly Func<Type, string, Type[], Type[], MethodInfo> AccessTools_Method;

		private static readonly Func<Type, string, PropertyInfo> AccessTools_Property;

		static AccessToolsShim()
		{
			All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			MethodInfo method = ClrTypes.AccessTools.GetMethod("Method", All, null, new Type[4]
			{
				typeof(Type),
				typeof(string),
				typeof(Type[]),
				typeof(Type[])
			}, null);
			MethodInfo? method2 = ClrTypes.AccessTools.GetMethod("Property", All, null, new Type[2]
			{
				typeof(Type),
				typeof(string)
			}, null);
			AccessTools_Method = (Func<Type, string, Type[], Type[], MethodInfo>)ExpressionHelper.CreateTypedFastInvoke(method);
			AccessTools_Property = (Func<Type, string, PropertyInfo>)ExpressionHelper.CreateTypedFastInvoke(method2);
		}

		public static MethodInfo Method(Type type, string name, params Type[] parameters)
		{
			return AccessTools_Method(type, name, parameters, null);
		}

		public static PropertyInfo Property(Type type, string name)
		{
			return AccessTools_Property(type, name);
		}
	}
}
namespace XUnity.Common.Extensions
{
	public static class ExceptionExtensions
	{
		public static TException FirstInnerExceptionOfType<TException>(this Exception e) where TException : Exception
		{
			for (Exception ex = e; ex != null; ex = ex.InnerException)
			{
				if (ex is TException)
				{
					return (TException)ex;
				}
			}
			return null;
		}
	}
	public static class ObjectExtensions
	{
		public static Type GetUnityType(this object obj)
		{
			return obj.GetType();
		}

		public static bool TryCastTo<TObject>(this object obj, out TObject castedObject)
		{
			if (obj is TObject val)
			{
				castedObject = val;
				return true;
			}
			castedObject = default(TObject);
			return false;
		}
	}
	public static class StreamExtensions
	{
		public static byte[] ReadFully(this Stream stream, int initialLength)
		{
			if (initialLength < 1)
			{
				initialLength = 32768;
			}
			byte[] array = new byte[initialLength];
			int num = 0;
			int num2;
			while ((num2 = stream.Read(array, num, array.Length - num)) > 0)
			{
				num += num2;
				if (num == array.Length)
				{
					int num3 = stream.ReadByte();
					if (num3 == -1)
					{
						return array;
					}
					byte[] array2 = new byte[array.Length * 2];
					Array.Copy(array, array2, array.Length);
					array2[num] = (byte)num3;
					array = array2;
					num++;
				}
			}
			byte[] array3 = new byte[num];
			Array.Copy(array, array3, num);
			return array3;
		}
	}
	public static class StringExtensions
	{
		private static readonly HashSet<char> InvalidFileNameChars = new HashSet<char>(Path.GetInvalidFileNameChars());

		public static string UseCorrectDirectorySeparators(this string path)
		{
			if (Path.DirectorySeparatorChar == '\\')
			{
				return path.Replace('/', Path.DirectorySeparatorChar);
			}
			if (Path.DirectorySeparatorChar == '/')
			{
				return path.Replace('\\', Path.DirectorySeparatorChar);
			}
			return path;
		}

		public static bool IsNullOrWhiteSpace(this string value)
		{
			if (value == null)
			{
				return true;
			}
			for (int i = 0; i < value.Length; i++)
			{
				if (!char.IsWhiteSpace(value[i]))
				{
					return false;
				}
			}
			return true;
		}

		public static string MakeRelativePath(this string fullOrRelativePath, string basePath)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int i = 0;
			bool flag = false;
			string[] array = basePath.Split(':', '\\', '/');
			List<string> list = fullOrRelativePath.Split(':', '\\', '/').ToList();
			if (array.Length == 0 || list.Count <= 0 || array[0] != list[0])
			{
				flag = true;
			}
			bool flag2 = false;
			for (int j = 0; j < list.Count; j++)
			{
				if (list[j] == "..")
				{
					if (flag2)
					{
						int num = j - 1;
						if (num >= 0)
						{
							list.RemoveAt(j);
							list.RemoveAt(num);
							j -= 2;
						}
					}
				}
				else
				{
					flag2 = true;
				}
			}
			if (!flag)
			{
				for (i = 1; i < array.Length && !(array[i] != list[i]); i++)
				{
				}
				for (int k = 0; k < array.Length - i; k++)
				{
					char directorySeparatorChar = Path.DirectorySeparatorChar;
					stringBuilder.Append(".." + directorySeparatorChar);
				}
			}
			for (int l = i; l < list.Count - 1; l++)
			{
				string value = list[l];
				stringBuilder.Append(value).Append(Path.DirectorySeparatorChar);
			}
			string value2 = list[^1];
			stringBuilder.Append(value2);
			return stringBuilder.ToString();
		}

		public static string SanitizeForFileSystem(this string path)
		{
			StringBuilder stringBuilder = new StringBuilder(path.Length);
			foreach (char c in path)
			{
				if (!InvalidFileNameChars.Contains(c))
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		public static string SplitToLines(this string text, int maxStringLength, params char[] splitOnCharacters)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num;
			for (int i = 0; text.Length > i; i += num)
			{
				if (i != 0)
				{
					stringBuilder.Append('\n');
				}
				num = ((i + maxStringLength <= text.Length) ? text.Substring(i, maxStringLength).LastIndexOfAny(splitOnCharacters) : (text.Length - i));
				num = ((num == -1) ? maxStringLength : num);
				stringBuilder.Append(text.Substring(i, num).Trim());
			}
			return stringBuilder.ToString();
		}

		public static bool StartsWithStrict(this string str, string prefix)
		{
			int num = Math.Min(str.Length, prefix.Length);
			if (num < prefix.Length)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				if (str[i] != prefix[i])
				{
					return false;
				}
			}
			return true;
		}

		public static string GetBetween(this string strSource, string strStart, string strEnd)
		{
			int num = strSource.IndexOf(strStart);
			if (num != -1)
			{
				num += strStart.Length;
				int num2 = strSource.IndexOf(strEnd, num);
				if (num2 > num)
				{
					return strSource.Substring(num, num2 - num);
				}
			}
			return string.Empty;
		}

		public static bool RemindsOf(this string that, string other)
		{
			if (!that.StartsWith(other) && !other.StartsWith(that) && !that.EndsWith(other))
			{
				return other.EndsWith(that);
			}
			return true;
		}
	}
}
namespace XUnity.Common.Constants
{
	public static class ClrTypes
	{
		public static readonly Type AccessTools = FindTypeStrict("Harmony.AccessTools, 0Harmony") ?? FindTypeStrict("HarmonyLib.AccessTools, 0Harmony") ?? FindTypeStrict("Harmony.AccessTools, MelonLoader.ModHandler") ?? FindTypeStrict("HarmonyLib.AccessTools, MelonLoader.ModHandler");

		public static readonly Type HarmonyMethod = FindTypeStrict("Harmony.HarmonyMethod, 0Harmony") ?? FindTypeStrict("HarmonyLib.HarmonyMethod, 0Harmony") ?? FindTypeStrict("Harmony.HarmonyMethod, MelonLoader.ModHandler") ?? FindTypeStrict("HarmonyLib.HarmonyMethod, MelonLoader.ModHandler");

		public static readonly Type HarmonyInstance = FindTypeStrict("Harmony.HarmonyInstance, 0Harmony") ?? FindTypeStrict("Harmony.HarmonyInstance, MelonLoader.ModHandler");

		public static readonly Type Harmony = FindTypeStrict("HarmonyLib.Harmony, 0Harmony") ?? FindTypeStrict("HarmonyLib.Harmony, MelonLoader.ModHandler");

		public static readonly Type Hook = FindTypeStrict("MonoMod.RuntimeDetour.Hook, MonoMod.RuntimeDetour");

		public static readonly Type Detour = FindTypeStrict("MonoMod.RuntimeDetour.Detour, MonoMod.RuntimeDetour");

		public static readonly Type NativeDetour = FindTypeStrict("MonoMod.RuntimeDetour.NativeDetour, MonoMod.RuntimeDetour");

		public static readonly Type DynamicMethodDefinition = FindTypeStrict("MonoMod.Utils.DynamicMethodDefinition, MonoMod.Utils");

		public static readonly Type Imports = FindTypeStrict("MelonLoader.Imports, MelonLoader.ModHandler");

		public static readonly Type MethodBase = FindType("System.Reflection.MethodBase");

		public static readonly Type Task = FindType("System.Threading.Tasks.Task");

		private static Type FindType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(name, throwOnError: false);
					if ((object)type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static Type FindTypeStrict(string name)
		{
			return Type.GetType(name, throwOnError: false);
		}
	}
	public class TypeContainer
	{
		public Type ClrType { get; }

		public Type UnityType { get; }

		public TypeContainer(Type type)
		{
			UnityType = type;
			ClrType = type;
		}

		public bool IsAssignableFrom(Type unityType)
		{
			if ((object)UnityType != null)
			{
				return UnityType.IsAssignableFrom(unityType);
			}
			return false;
		}
	}
	public static class UnityFeatures
	{
		private static readonly BindingFlags All;

		public static bool SupportsMouseScrollDelta { get; }

		public static bool SupportsClipboard { get; }

		public static bool SupportsCustomYieldInstruction { get; }

		public static bool SupportsSceneManager { get; }

		public static bool SupportsWaitForSecondsRealtime { get; set; }

		static UnityFeatures()
		{
			All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			SupportsMouseScrollDelta = false;
			SupportsClipboard = false;
			SupportsCustomYieldInstruction = false;
			SupportsSceneManager = false;
			SupportsWaitForSecondsRealtime = false;
			try
			{
				SupportsClipboard = (object)UnityTypes.TextEditor?.ClrType.GetProperty("text")?.GetSetMethod() != null;
			}
			catch (Exception)
			{
			}
			try
			{
				SupportsCustomYieldInstruction = UnityTypes.CustomYieldInstruction != null;
			}
			catch (Exception)
			{
			}
			try
			{
				SupportsSceneManager = UnityTypes.Scene != null && UnityTypes.SceneManager != null && (object)UnityTypes.SceneManager.ClrType.GetMethod("add_sceneLoaded", All) != null;
			}
			catch (Exception)
			{
			}
			try
			{
				SupportsMouseScrollDelta = (object)UnityTypes.Input?.ClrType.GetProperty("mouseScrollDelta") != null;
			}
			catch (Exception)
			{
			}
			try
			{
				SupportsWaitForSecondsRealtime = UnityTypes.WaitForSecondsRealtime != null;
			}
			catch (Exception)
			{
			}
		}
	}
	public static class UnityTypes
	{
		public static class TMP_Settings_Properties
		{
			public static CachedProperty Version = TMP_Settings?.ClrType.CachedProperty("version");

			public static CachedProperty FallbackFontAssets = TMP_Settings?.ClrType.CachedProperty("fallbackFontAssets");
		}

		public static class TMP_FontAsset_Properties
		{
			public static CachedProperty Version = TMP_FontAsset?.ClrType.CachedProperty("version");
		}

		public static class AdvScenarioData_Properties
		{
			public static CachedProperty ScenarioLabels = AdvScenarioData?.ClrType.CachedProperty("ScenarioLabels");
		}

		public static class UguiNovelText_Properties
		{
			public static CachedProperty TextGenerator = UguiNovelText?.ClrType.CachedProperty("TextGenerator");
		}

		public static class UguiNovelText_Methods
		{
			public static CachedMethod SetAllDirty = UguiNovelText?.ClrType.CachedMethod("SetAllDirty");
		}

		public static class UguiNovelTextGenerator_Methods
		{
			public static CachedMethod Refresh = UguiNovelTextGenerator?.ClrType.CachedMethod("Refresh");
		}

		public static class AdvUguiMessageWindow_Properties
		{
			public static CachedProperty Text = AdvUguiMessageWindow?.ClrType.CachedProperty("Text");

			public static CachedProperty Engine = AdvUguiMessageWindow?.ClrType.CachedProperty("Engine");
		}

		public static class AdvUiMessageWindow_Fields
		{
			public static CachedField text = AdvUiMessageWindow?.ClrType.CachedField("text");

			public static CachedField nameText = AdvUiMessageWindow?.ClrType.CachedField("nameText");
		}

		public static class AdvUguiMessageWindow_Fields
		{
			public static FieldInfo text = AdvUguiMessageWindow?.ClrType.GetField("text", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

			public static FieldInfo nameText = AdvUguiMessageWindow?.ClrType.GetField("nameText", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

			public static FieldInfo engine = AdvUguiMessageWindow?.ClrType.GetField("engine", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		}

		public static class AdvEngine_Properties
		{
			public static CachedProperty Page = AdvEngine?.ClrType.CachedProperty("Page");
		}

		public static class AdvPage_Methods
		{
			public static CachedMethod RemakeTextData = AdvPage?.ClrType.CachedMethod("RemakeTextData");

			public static CachedMethod RemakeText = AdvPage?.ClrType.CachedMethod("RemakeText");

			public static CachedMethod ChangeMessageWindowText = AdvPage?.ClrType.CachedMethod("ChangeMessageWindowText", typeof(string), typeof(string), typeof(string), typeof(string));
		}

		public static class UILabel_Properties
		{
			public static CachedProperty MultiLine = UILabel?.ClrType.CachedProperty("multiLine");

			public static CachedProperty OverflowMethod = UILabel?.ClrType.CachedProperty("overflowMethod");

			public static CachedProperty SpacingX = UILabel?.ClrType.CachedProperty("spacingX");

			public static CachedProperty UseFloatSpacing = UILabel?.ClrType.CachedProperty("useFloatSpacing");
		}

		public static class Text_Properties
		{
			public static CachedProperty Font = Text?.ClrType.CachedProperty("font");

			public static CachedProperty FontSize = Text?.ClrType.CachedProperty("fontSize");

			public static CachedProperty HorizontalOverflow = Text?.ClrType.CachedProperty("horizontalOverflow");

			public static CachedProperty VerticalOverflow = Text?.ClrType.CachedProperty("verticalOverflow");

			public static CachedProperty LineSpacing = Text?.ClrType.CachedProperty("lineSpacing");

			public static CachedProperty ResizeTextForBestFit = Text?.ClrType.CachedProperty("resizeTextForBestFit");

			public static CachedProperty ResizeTextMinSize = Text?.ClrType.CachedProperty("resizeTextMinSize");

			public static CachedProperty ResizeTextMaxSize = Text?.ClrType.CachedProperty("resizeTextMaxSize");
		}

		public static class InputField_Properties
		{
			public static CachedProperty Placeholder = InputField?.ClrType.CachedProperty("placeholder");
		}

		public static class TMP_InputField_Properties
		{
			public static CachedProperty Placeholder = TMP_InputField?.ClrType.CachedProperty("placeholder");
		}

		public static class Font_Properties
		{
			public static CachedProperty FontSize = Font?.ClrType.CachedProperty("fontSize");
		}

		public static class AssetBundle_Methods
		{
			public static CachedMethod LoadAll = AssetBundle?.ClrType.CachedMethod("LoadAll", typeof(Type));

			public static CachedMethod LoadAllAssets = AssetBundle?.ClrType.CachedMethod("LoadAllAssets", typeof(Type));

			public static CachedMethod LoadFromFile = AssetBundle?.ClrType.CachedMethod("LoadFromFile", typeof(string));

			public static CachedMethod CreateFromFile = AssetBundle?.ClrType.CachedMethod("CreateFromFile", typeof(string));
		}

		public static class TextExpansion_Methods
		{
			public static CachedMethod SetMessageType = TextExpansion?.ClrType.CachedMethod("SetMessageType");

			public static CachedMethod SkipTypeWriter = TextExpansion?.ClrType.CachedMethod("SkipTypeWriter");
		}

		public static class GameObject_Methods
		{
		}

		public static class TextMesh_Methods
		{
		}

		public static class Text_Methods
		{
		}

		public static class InputField_Methods
		{
		}

		public static class TMP_Text_Methods
		{
		}

		public static class TMP_InputField_Methods
		{
		}

		public static class TextMeshPro_Methods
		{
		}

		public static class TextMeshProUGUI_Methods
		{
		}

		public static class UILabel_Methods
		{
		}

		public static class UIRect_Methods
		{
		}

		public static class SceneManager_Methods
		{
			public static readonly Action<UnityAction<Scene, LoadSceneMode>> add_sceneLoaded = (Action<UnityAction<Scene, LoadSceneMode>>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(SceneManager).GetMethod("add_sceneLoaded", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(UnityAction<Scene, LoadSceneMode>) }, null));
		}

		public static class Texture2D_Methods
		{
			public static readonly Func<Texture2D, byte[], bool> LoadImage = (Func<Texture2D, byte[], bool>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null));

			public static readonly Func<Texture2D, byte[]> EncodeToPNG = (Func<Texture2D, byte[]>)ExpressionHelper.CreateTypedFastInvokeUnchecked(typeof(Texture2D).GetMethod("EncodeToPNG", BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null));
		}

		public static class ImageConversion_Methods
		{
			public static readonly Func<Texture2D, byte[], bool, bool> LoadImage = (Func<Texture2D, byte[], bool, bool>)ExpressionHelper.CreateTypedFastInvokeUnchecked(ImageConversion?.ClrType.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			}, null));

			public static readonly Func<Texture2D, byte[]> EncodeToPNG = (Func<Texture2D, byte[]>)ExpressionHelper.CreateTypedFastInvokeUnchecked(ImageConversion?.ClrType.GetMethod("EncodeToPNG", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Texture2D) }, null));
		}

		public static readonly TypeContainer UILabel = FindType("UILabel");

		public static readonly TypeContainer UIWidget = FindType("UIWidget");

		public static readonly TypeContainer UIAtlas = FindType("UIAtlas");

		public static readonly TypeContainer UISprite = FindType("UISprite");

		public static readonly TypeContainer UITexture = FindType("UITexture");

		public static readonly TypeContainer UI2DSprite = FindType("UI2DSprite");

		public static readonly TypeContainer UIFont = FindType("UIFont");

		public static readonly TypeContainer UIPanel = FindType("UIPanel");

		public static readonly TypeContainer UIRect = FindType("UIRect");

		public static readonly TypeContainer UIInput = FindType("UIInput");

		public static readonly TypeContainer TextField = FindType("FairyGUI.TextField");

		public static readonly TypeContainer TMP_InputField = FindType("TMPro.TMP_InputField");

		public static readonly TypeContainer TMP_Text = FindType("TMPro.TMP_Text");

		public static readonly TypeContainer TextMeshProUGUI = FindType("TMPro.TextMeshProUGUI");

		public static readonly TypeContainer TextMeshPro = FindType("TMPro.TextMeshPro");

		public static readonly TypeContainer TMP_FontAsset = FindType("TMPro.TMP_FontAsset");

		public static readonly TypeContainer TMP_Settings = FindType("TMPro.TMP_Settings");

		public static readonly TypeContainer GameObject = FindType("UnityEngine.GameObject");

		public static readonly TypeContainer Transform = FindType("UnityEngine.Transform");

		public static readonly TypeContainer TextMesh = FindType("UnityEngine.TextMesh");

		public static readonly TypeContainer Text = FindType("UnityEngine.UI.Text");

		public static readonly TypeContainer Image = FindType("UnityEngine.UI.Image");

		public static readonly TypeContainer RawImage = FindType("UnityEngine.UI.RawImage");

		public static readonly TypeContainer MaskableGraphic = FindType("UnityEngine.UI.MaskableGraphic");

		public static readonly TypeContainer Graphic = FindType("UnityEngine.UI.Graphic");

		public static readonly TypeContainer GUIContent = FindType("UnityEngine.GUIContent");

		public static readonly TypeContainer WWW = FindType("UnityEngine.WWW");

		public static readonly TypeContainer InputField = FindType("UnityEngine.UI.InputField");

		public static readonly TypeContainer GUI = FindType("UnityEngine.GUI");

		public static readonly TypeContainer GUI_ToolbarButtonSize = FindType("UnityEngine.GUI+ToolbarButtonSize");

		public static readonly TypeContainer GUIStyle = FindType("UnityEngine.GUIStyle");

		public static readonly TypeContainer ImageConversion = FindType("UnityEngine.ImageConversion");

		public static readonly TypeContainer Texture2D = FindType("UnityEngine.Texture2D");

		public static readonly TypeContainer Texture = FindType("UnityEngine.Texture");

		public static readonly TypeContainer SpriteRenderer = FindType("UnityEngine.SpriteRenderer");

		public static readonly TypeContainer Sprite = FindType("UnityEngine.Sprite");

		public static readonly TypeContainer Object = FindType("UnityEngine.Object");

		public static readonly TypeContainer TextEditor = FindType("UnityEngine.TextEditor");

		public static readonly TypeContainer CustomYieldInstruction = FindType("UnityEngine.CustomYieldInstruction");

		public static readonly TypeContainer SceneManager = FindType("UnityEngine.SceneManagement.SceneManager");

		public static readonly TypeContainer Scene = FindType("UnityEngine.SceneManagement.Scene");

		public static readonly TypeContainer UnityEventBase = FindType("UnityEngine.Events.UnityEventBase");

		public static readonly TypeContainer BaseInvokableCall = FindType("UnityEngine.Events.BaseInvokableCall");

		public static readonly TypeContainer Font = FindType("UnityEngine.Font");

		public static readonly TypeContainer WaitForSecondsRealtime = FindType("UnityEngine.WaitForSecondsRealtime");

		public static readonly TypeContainer Input = FindType("UnityEngine.Input");

		public static readonly TypeContainer AssetBundleCreateRequest = FindType("UnityEngine.AssetBundleCreateRequest");

		public static readonly TypeContainer AssetBundle = FindType("UnityEngine.AssetBundle");

		public static readonly TypeContainer AssetBundleRequest = FindType("UnityEngine.AssetBundleRequest");

		public static readonly TypeContainer Resources = FindType("UnityEngine.Resources");

		public static readonly TypeContainer AsyncOperation = FindType("UnityEngine.AsyncOperation");

		public static readonly TypeContainer TextAsset = FindType("UnityEngine.TextAsset");

		public static readonly Type HorizontalWrapMode = FindClrType("UnityEngine.HorizontalWrapMode");

		public static readonly Type TextOverflowModes = FindClrType("TMPro.TextOverflowModes");

		public static readonly Type TextAlignmentOptions = FindClrType("TMPro.TextAlignmentOptions");

		public static readonly Type VerticalWrapMode = FindClrType("UnityEngine.VerticalWrapMode");

		public static readonly TypeContainer TextExpansion = FindType("UnityEngine.UI.TextExpansion");

		public static readonly TypeContainer Typewriter = FindType("Typewriter");

		public static readonly TypeContainer UguiNovelText = FindType("Utage.UguiNovelText");

		public static readonly TypeContainer UguiNovelTextGenerator = FindType("Utage.UguiNovelTextGenerator");

		public static readonly TypeContainer AdvEngine = FindType("Utage.AdvEngine");

		public static readonly TypeContainer AdvPage = FindType("Utage.AdvPage");

		public static readonly TypeContainer TextData = FindType("Utage.TextData");

		public static readonly TypeContainer AdvUguiMessageWindow = FindType("Utage.AdvUguiMessageWindow") ?? FindType("AdvUguiMessageWindow");

		public static readonly TypeContainer AdvUiMessageWindow = FindType("AdvUiMessageWindow");

		public static readonly TypeContainer AdvDataManager = FindType("Utage.AdvDataManager");

		public static readonly TypeContainer AdvScenarioData = FindType("Utage.AdvScenarioData");

		public static readonly TypeContainer AdvScenarioLabelData = FindType("Utage.AdvScenarioLabelData");

		public static readonly TypeContainer DicingTextures = FindType("Utage.DicingTextures");

		public static readonly TypeContainer DicingImage = FindType("Utage.DicingImage");

		public static readonly TypeContainer TextArea2D = FindType("Utage.TextArea2D");

		public static readonly TypeContainer CubismRenderer = FindType("Live2D.Cubism.Rendering.CubismRenderer");

		public static readonly TypeContainer TextWindow = FindType("Assets.System.Text.TextWindow");

		private static Type FindClrType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(name, throwOnError: false);
					if ((object)type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static TypeContainer FindType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(name, throwOnError: false);
					if ((object)type != null)
					{
						return new TypeContainer(type);
					}
				}
				catch
				{
				}
			}
			return null;
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/ExIni.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Win32;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyInformationalVersion("GIT master [cf85ca6f3fc361cf48bf56107e4cec9102b7f5eb] ")]
[assembly: AssemblyTitle("ExIni")]
[assembly: Guid("b8adf1ac-aade-485a-8997-14c4b42e0a8b")]
[assembly: AssemblyDescription("Extended INI File Handler")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("1.0.2.1")]
[assembly: AssemblyCompany("Usagirei")]
[assembly: AssemblyProduct("ExIni")]
[assembly: ComVisible(false)]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCopyright("Copyright © Usagirei 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.0.2.1")]
namespace ExIni;

public class IniComment
{
	public List<string> Comments { get; set; }

	public IniComment()
	{
		Comments = new List<string>();
	}

	public override string ToString()
	{
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < Comments.Count; i++)
		{
			string text = Comments[i];
			string value = ((i < Comments.Count - 1) ? (";" + text + Environment.NewLine) : (";" + text));
			stringBuilder.Append(value);
		}
		return stringBuilder.ToString();
	}

	public void Append(params string[] comments)
	{
		Comments.AddRange(comments);
	}
}
public class IniFile
{
	private readonly IniComment _comments;

	private readonly List<IniSection> _sections;

	public IniSection this[string sec] => CreateSection(sec);

	public IniComment Comments => _comments;

	public List<IniSection> Sections => _sections;

	public IniFile()
	{
		_comments = new IniComment();
		_sections = new List<IniSection>();
	}

	public override string ToString()
	{
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < Sections.Count; i++)
		{
			IniSection iniSection = Sections[i];
			if (iniSection.Comments.Comments.Any())
			{
				stringBuilder.AppendLine(iniSection.Comments.ToString());
			}
			stringBuilder.AppendLine(iniSection.ToString());
			foreach (IniKey key in iniSection.Keys)
			{
				if (key.Comments.Comments.Any())
				{
					stringBuilder.AppendLine(key.Comments.ToString());
				}
				stringBuilder.AppendLine(key.ToString());
			}
			if (i < Sections.Count - 1)
			{
				stringBuilder.AppendLine();
			}
		}
		if (Comments.Comments.Any())
		{
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(Comments.ToString());
		}
		return stringBuilder.ToString();
	}

	public IniSection CreateSection(string section)
	{
		IniSection section2 = GetSection(section);
		if (section2 != null)
		{
			return section2;
		}
		IniSection iniSection = new IniSection(section);
		_sections.Add(iniSection);
		return iniSection;
	}

	public bool DeleteSection(string section)
	{
		if (!HasSection(section))
		{
			return false;
		}
		Sections.Remove(GetSection(section));
		return true;
	}

	public IniSection GetSection(string section)
	{
		if (!HasSection(section))
		{
			return null;
		}
		return _sections.FirstOrDefault((IniSection iniSection) => iniSection.Section == section);
	}

	public bool HasSection(string section)
	{
		return _sections.Any((IniSection iniSection) => iniSection.Section == section);
	}

	public void Merge(IniFile ini)
	{
		Comments.Append(ini.Comments.Comments.ToArray());
		foreach (IniSection section in ini.Sections)
		{
			IniSection iniSection = this[section.Section];
			iniSection.Comments.Append(section.Comments.Comments.ToArray());
			foreach (IniKey key in section.Keys)
			{
				IniKey iniKey = iniSection[key.Key];
				iniKey.Comments.Append(key.Comments.Comments.ToArray());
				iniKey.Value = key.Value;
			}
		}
	}

	public void Save(string filePath)
	{
		string directoryName = Path.GetDirectoryName(filePath);
		if (!string.IsNullOrEmpty(directoryName))
		{
			Directory.CreateDirectory(directoryName);
		}
		File.WriteAllText(filePath, ToString(), Encoding.UTF8);
	}

	public static IniFile FromFile(string iniString)
	{
		return IniParser.Parse(File.ReadAllText(iniString));
	}

	public static IniFile FromString(string iniString)
	{
		return IniParser.Parse(iniString);
	}
}
public class IniKey
{
	private readonly IniComment _comments;

	public IniComment Comments => _comments;

	public string Key { get; set; }

	public string RawValue { get; set; }

	public string Value
	{
		get
		{
			return Resolve(RawValue);
		}
		set
		{
			RawValue = value;
		}
	}

	public IniKey(string key, string value = null)
	{
		Key = key;
		Value = value;
		_comments = new IniComment();
	}

	public override string ToString()
	{
		return $"{Key}={RawValue}";
	}

	private static string GetEnvironment(string env)
	{
		return Environment.ExpandEnvironmentVariables(env);
	}

	private static string GetRegistry(string path)
	{
		string directoryName = Path.GetDirectoryName(path);
		string fileName = Path.GetFileName(path);
		if (string.IsNullOrEmpty(directoryName))
		{
			return null;
		}
		return Registry.GetValue(directoryName, fileName, string.Empty)?.ToString();
	}

	private static string Resolve(string value)
	{
		if (value == null)
		{
			return null;
		}
		Regex regex = new Regex("\\$\\((?<reg>.*)\\)");
		Regex regex2 = new Regex("%.*%");
		while (regex.IsMatch(value) || regex2.IsMatch(value))
		{
			value = regex.Replace(value, (Match match) => GetRegistry(match.Groups["reg"].Value));
			value = GetEnvironment(value);
		}
		return value;
	}
}
internal class IniParser
{
	private static readonly Regex CommentRegex = new Regex("^;(?<com>.*)");

	private static readonly Regex KeyRegex = new Regex("^(?<key>[\\w\\s]+)=(?<val>.*)$");

	private static readonly Regex SectionRegex = new Regex("^\\[(?<sec>[\\w\\s]+)\\]$");

	private static readonly Regex VarRegex = new Regex("^\\@(?<key>[\\w\\s]+)=(?<val>.*)$");

	public static IniFile Parse(string iniString)
	{
		IniFile iniFile = new IniFile();
		string[] array = (from line in iniString.Split(new char[1] { '\n' })
			let trimmed = line.Trim()
			select trimmed.TrimEnd(new char[1] { '\r' })).ToArray();
		List<string> list = new List<string>();
		IniSection iniSection = null;
		bool flag = false;
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i];
			if (string.IsNullOrEmpty(text))
			{
				continue;
			}
			if (IsComment(text))
			{
				string comment = GetComment(text);
				list.Add(comment);
				if (IsVariable(comment))
				{
					string[] variable = GetVariable(comment);
					string variable2 = variable[0];
					string value = variable[1];
					Environment.SetEnvironmentVariable(variable2, value);
				}
				flag = true;
			}
			else if (IsSection(text))
			{
				iniSection = iniFile[GetSection(text)];
				if (flag)
				{
					iniSection.Comments.Append(list.ToArray());
					list.Clear();
					flag = false;
				}
			}
			else if (IsKey(text))
			{
				if (iniSection == null)
				{
					throw new Exception($"{i}: Sectionless Key Value Pair");
				}
				string[] key = GetKey(text);
				string key2 = key[0];
				string value2 = key[1];
				if (flag)
				{
					iniSection[key2].Comments.Append(list.ToArray());
					list.Clear();
					flag = false;
				}
				iniSection[key2].Value = value2;
			}
		}
		if (flag)
		{
			iniFile.Comments.Append(list.ToArray());
		}
		return iniFile;
	}

	private static string GetComment(string line)
	{
		return CommentRegex.Match(line).Groups["com"].Value;
	}

	private static string[] GetKey(string line)
	{
		Match match = KeyRegex.Match(line);
		return new string[2]
		{
			match.Groups["key"].Value,
			match.Groups["val"].Value
		};
	}

	private static string GetSection(string line)
	{
		return SectionRegex.Match(line).Groups["sec"].Value;
	}

	private static string[] GetVariable(string line)
	{
		Match match = VarRegex.Match(line);
		return new string[2]
		{
			match.Groups["key"].Value,
			match.Groups["val"].Value
		};
	}

	private static bool IsComment(string line)
	{
		return CommentRegex.IsMatch(line);
	}

	private static bool IsKey(string line)
	{
		return KeyRegex.IsMatch(line);
	}

	private static bool IsSection(string line)
	{
		return SectionRegex.IsMatch(line);
	}

	private static bool IsVariable(string line)
	{
		return VarRegex.IsMatch(line);
	}
}
public class IniSection
{
	private readonly IniComment _comments;

	private readonly List<IniKey> _keys;

	public IniKey this[string key] => CreateKey(key);

	public IniComment Comments => _comments;

	public List<IniKey> Keys => _keys;

	public string Section { get; set; }

	public IniSection(string section)
	{
		Section = section;
		_comments = new IniComment();
		_keys = new List<IniKey>();
	}

	public override string ToString()
	{
		return $"[{Section}]";
	}

	public IniKey CreateKey(string key)
	{
		IniKey key2 = GetKey(key);
		if (key2 != null)
		{
			return key2;
		}
		IniKey iniKey = new IniKey(key);
		_keys.Add(iniKey);
		return iniKey;
	}

	public IniKey GetKey(string key)
	{
		if (!HasKey(key))
		{
			return null;
		}
		return _keys.FirstOrDefault((IniKey iniKey) => iniKey.Key == key);
	}

	public bool HasKey(string key)
	{
		return _keys.Any((IniKey iniKey) => iniKey.Key == key);
	}

	public bool DeleteKey(string key)
	{
		if (!HasKey(key))
		{
			return false;
		}
		Keys.Remove(GetKey(key));
		return true;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/BaiduTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core;
using XUnity.AutoTranslator.Plugin.Core.Constants;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Extensions;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;
using XUnity.Common.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("BaiduTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BaiduTranslate")]
[assembly: AssemblyTitle("BaiduTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BaiduTranslate;

internal class BaiduTranslateEndpoint : HttpEndpoint
{
	private static readonly Dictionary<string, string> SupportedLanguages = new Dictionary<string, string>
	{
		{ "en", "en" },
		{ "ja", "jp" },
		{ "jp", "jp" },
		{ "zh", "zh" },
		{ "zh-Hans", "zh" },
		{ "zh-CN", "zh" },
		{ "zh-Hant", "cht" },
		{ "zh-TW", "cht" },
		{ "ko", "kor" },
		{ "kor", "kor" },
		{ "fra", "fra" },
		{ "fr", "fra" },
		{ "spa", "spa" },
		{ "es", "spa" },
		{ "ara", "ara" },
		{ "ar", "ara" },
		{ "bg", "bul" },
		{ "bul", "bul" },
		{ "et", "est" },
		{ "est", "est" },
		{ "da", "dan" },
		{ "dan", "dan" },
		{ "fi", "fin" },
		{ "fin", "fin" },
		{ "ro", "rom" },
		{ "rom", "rom" },
		{ "sl", "slo" },
		{ "slo", "slo" },
		{ "vi", "vie" },
		{ "vie", "vie" },
		{ "sv", "swe" },
		{ "swe", "swe" },
		{ "th", "th" },
		{ "ru", "ru" },
		{ "pt", "pt" },
		{ "de", "de" },
		{ "it", "it" },
		{ "el", "el" },
		{ "nl", "nl" },
		{ "pl", "pl" },
		{ "cs", "cs" },
		{ "hu", "hu" }
	};

	private static readonly string HttpServicePointTemplateUrl = "https://api.fanyi.baidu.com/api/trans/vip/translate?q={0}&from={1}&to={2}&appid={3}&salt={4}&sign={5}";

	private static readonly MD5 HashMD5 = MD5.Create();

	private string _appId;

	private string _appSecret;

	private float _delay;

	private float _lastRequestTimestamp;

	public override string Id => "BaiduTranslate";

	public override string FriendlyName => "Baidu Translator";

	private string FixLanguage(string lang)
	{
		if (SupportedLanguages.TryGetValue(lang, out var value))
		{
			return value;
		}
		return lang;
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		_appId = context.GetOrCreateSetting<string>("Baidu", "BaiduAppId", "");
		_appSecret = context.GetOrCreateSetting<string>("Baidu", "BaiduAppSecret", "");
		_delay = context.GetOrCreateSetting<float>("Baidu", "DelaySeconds", 1f);
		if (string.IsNullOrEmpty(_appId))
		{
			throw new EndpointInitializationException("The BaiduTranslate endpoint requires an App Id which has not been provided.");
		}
		if (string.IsNullOrEmpty(_appSecret))
		{
			throw new EndpointInitializationException("The BaiduTranslate endpoint requires an App Secret which has not been provided.");
		}
		context.DisableCertificateChecksFor(new string[1] { "api.fanyi.baidu.com" });
		if (!SupportedLanguages.ContainsKey(context.SourceLanguage))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.ContainsKey(context.DestinationLanguage))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context)
	{
		float realtimeSinceStartup = TimeHelper.realtimeSinceStartup;
		float num = realtimeSinceStartup - _lastRequestTimestamp;
		if (num < _delay)
		{
			float num2 = _delay - num;
			object obj = CoroutineHelper.CreateWaitForSecondsRealtime(num2);
			if (obj != null)
			{
				yield return obj;
			}
			else
			{
				float end = realtimeSinceStartup + num2;
				while (realtimeSinceStartup < end)
				{
					yield return null;
				}
			}
		}
		_lastRequestTimestamp = TimeHelper.realtimeSinceStartup;
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		string text = DateTime.UtcNow.Millisecond.ToString();
		string text2 = CreateMD5(_appId + ((ITranslationContextBase)context).UntranslatedText + text + _appSecret);
		XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpServicePointTemplateUrl, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), _appId, text, text2));
		val.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent);
		val.Headers[HttpRequestHeader.AcceptCharset] = "UTF-8";
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		string data = ((IHttpResponseInspectionContext)context).Response.Data;
		if (data.StartsWith("{\"error"))
		{
			return;
		}
		JSONNode val = JSON.Parse(data);
		StringBuilder stringBuilder = new StringBuilder(data.Length);
		Enumerator enumerator = ((JSONNode)((JSONNode)val.AsObject)["trans_result"].AsArray).GetEnumerator();
		while (((Enumerator)(ref enumerator)).MoveNext())
		{
			string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsObject)["dst"]).ToString();
			text = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder))
			{
				stringBuilder.Append("\n");
			}
			stringBuilder.Append(text);
		}
		string text2 = stringBuilder.ToString();
		context.Complete(text2);
	}

	private static string CreateMD5(string input)
	{
		byte[] bytes = Encoding.UTF8.GetBytes(input);
		byte[] array = HashMD5.ComputeHash(bytes);
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < array.Length; i++)
		{
			stringBuilder.Append(array[i].ToString("X2"));
		}
		return stringBuilder.ToString().ToLower();
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/BingTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core;
using XUnity.AutoTranslator.Plugin.Core.Constants;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Shims;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;
using XUnity.Common.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("BingTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BingTranslate")]
[assembly: AssemblyTitle("BingTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BingTranslate;

public class BingTranslateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"auto-detect", "af", "ar", "bn", "bs", "bg", "yue", "ca", "zh-Hans", "zh-Hant",
		"hr", "cs", "da", "nl", "en", "et", "fj", "fil", "fi", "fr",
		"de", "el", "ht", "he", "hi", "mww", "hu", "is", "id", "it",
		"ja", "sw", "tlh", "tlh-Qaak", "ko", "lv", "lt", "mg", "ms", "mt",
		"nb", "fa", "pl", "pt", "otq", "ro", "ru", "sm", "sr-Cyrl", "sr-Latn",
		"sk", "sl", "es", "sv", "ty", "ta", "te", "th", "to", "tr",
		"uk", "ur", "vi", "cy", "yua"
	};

	private static readonly string HttpsServicePointTemplateUrl = "https://www.bing.com/ttranslatev3?isVertical=1&&IG={0}&IID={1}.{2}";

	private static readonly string HttpsServicePointTemplateUrlWithoutIG = "https://www.bing.com/ttranslatev3?isVertical=1";

	private static readonly string HttpsTranslateUserSite = "https://www.bing.com/translator";

	private static readonly string RequestTemplate = "&fromLang={1}&text={0}&to={2}";

	private static readonly Random RandomNumbers = new Random();

	private static readonly string[] Accepts = new string[1] { "*/*" };

	private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" };

	private static readonly string[] Referers = new string[1] { "https://bing.com/translator" };

	private static readonly string[] Origins = new string[1] { "https://www.bing.com" };

	private static readonly string[] AcceptCharsets = new string[2]
	{
		null,
		Encoding.UTF8.WebName
	};

	private static readonly string[] ContentTypes = new string[1] { "application/x-www-form-urlencoded" };

	private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)];

	private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)];

	private static readonly string Referer = Referers[RandomNumbers.Next(Referers.Length)];

	private static readonly string Origin = Origins[RandomNumbers.Next(Origins.Length)];

	private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)];

	private static readonly string ContentType = ContentTypes[RandomNumbers.Next(ContentTypes.Length)];

	private CookieContainer _cookieContainer;

	private bool _hasSetup;

	private string _ig;

	private string _iid;

	private int _translationCount;

	private int _resetAfter = RandomNumbers.Next(75, 125);

	public override string Id => "BingTranslate";

	public override string FriendlyName => "Bing Translator";

	public BingTranslateEndpoint()
	{
		_cookieContainer = new CookieContainer();
	}

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-CN":
		case "zh":
			return "zh-Hans";
		case "zh-TW":
			return "zh-Hant";
		case "auto":
			return "auto-detect";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		context.DisableCertificateChecksFor(new string[1] { "www.bing.com" });
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context)
	{
		if (!_hasSetup || _translationCount % _resetAfter == 0)
		{
			_resetAfter = RandomNumbers.Next(75, 125);
			_translationCount = 0;
			_hasSetup = true;
			IEnumerator enumerator = SetupIGAndIID();
			while (enumerator.MoveNext())
			{
				yield return enumerator.Current;
			}
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		_translationCount++;
		string text = null;
		text = ((_ig != null && _iid != null) ? string.Format(HttpsServicePointTemplateUrl, _ig, _iid, _translationCount) : HttpsServicePointTemplateUrlWithoutIG);
		string text2 = string.Format(RequestTemplate, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage));
		XUnityWebRequest val = new XUnityWebRequest("POST", text, text2);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: true);
		context.Complete(val);
	}

	public override void OnInspectResponse(IHttpResponseInspectionContext context)
	{
		InspectResponse(context.Response);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		string text = ((object)((JSONNode)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsArray)[0]["translations"].AsArray)[0]["text"]).ToString();
		string text2 = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
		context.Complete(text2);
	}

	private XUnityWebRequest CreateWebSiteRequest()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(HttpsTranslateUserSite);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: false);
		return val;
	}

	private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest)
	{
		request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent);
		if (AcceptLanguage != null)
		{
			request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage;
		}
		if (Accept != null)
		{
			request.Headers[HttpRequestHeader.Accept] = Accept;
		}
		if (Referer != null && isTranslationRequest)
		{
			request.Headers[HttpRequestHeader.Referer] = Referer;
		}
		if (Origin != null && isTranslationRequest)
		{
			request.Headers["Origin"] = Origin;
		}
		if (AcceptCharset != null)
		{
			request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset;
		}
		if (ContentType != null && isTranslationRequest)
		{
			request.Headers[HttpRequestHeader.ContentType] = ContentType;
		}
	}

	private void InspectResponse(XUnityWebResponse response)
	{
		CookieCollection newCookies = response.NewCookies;
		_cookieContainer.Add(newCookies);
	}

	public IEnumerator SetupIGAndIID()
	{
		_cookieContainer = new CookieContainer();
		XUnityWebResponse response;
		try
		{
			XUnityWebClient val = new XUnityWebClient();
			XUnityWebRequest val2 = CreateWebSiteRequest();
			response = val.Send(val2);
		}
		catch (Exception ex)
		{
			XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up BingTranslate IG. Proceeding without...");
			yield break;
		}
		IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator();
		while (iterator.MoveNext())
		{
			yield return iterator.Current;
		}
		if (((CustomYieldInstructionShim)response).IsTimedOut)
		{
			XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up BingTranslate IG. Proceeding without...");
			yield break;
		}
		if (response.Error != null)
		{
			XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up BingTranslate IG. Proceeding without...");
			yield break;
		}
		if (response.Data == null)
		{
			XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up BingTranslate IG. Proceeding without...");
			yield break;
		}
		InspectResponse(response);
		try
		{
			string data = response.Data;
			_ig = Lookup("\",IG:\"", data);
			_iid = Lookup("data-iid=\"", data);
			if (_ig == null || _iid == null)
			{
				XuaLogger.AutoTranslator.Warn("An error occurred while setting up BingTranslate IG/IID. Proceeding without...");
			}
		}
		catch (Exception ex2)
		{
			XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up BingTranslate IG. Proceeding without...");
		}
	}

	private string Lookup(string lookFor, string html)
	{
		int num = html.IndexOf(lookFor);
		if (num > -1)
		{
			int num2 = num + lookFor.Length;
			int num3 = html.IndexOf("\"", num2);
			if (num2 > -1 && num3 > -1)
			{
				return html.Substring(num2, num3 - num2);
			}
		}
		return null;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/BingTranslateLegitimate.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("BingTranslateLegitimate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BingTranslateLegitimate")]
[assembly: AssemblyTitle("BingTranslateLegitimate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BingTranslateLegitimate;

public class BingTranslateLegitimateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"af", "ar", "bn", "bs", "bg", "yue", "ca", "zh-Hans", "zh-Hant", "hr",
		"cs", "da", "nl", "en", "et", "fj", "fil", "fi", "fr", "de",
		"el", "ht", "he", "hi", "mww", "hu", "is", "id", "it", "ja",
		"sw", "tlh", "tlh-Qaak", "ko", "lv", "lt", "mg", "ms", "mt", "nb",
		"fa", "pl", "pt", "otq", "ro", "ru", "sm", "sr-Cyrl", "sr-Latn", "sk",
		"sl", "es", "sv", "ty", "ta", "te", "th", "to", "tr", "uk",
		"ur", "vi", "cy", "yua"
	};

	private static readonly string HttpsServicePointTemplateUrl = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from={0}&to={1}";

	private static readonly Random RandomNumbers = new Random();

	private static readonly string[] Accepts = new string[1] { "application/json" };

	private static readonly string[] ContentTypes = new string[1] { "application/json" };

	private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)];

	private static readonly string ContentType = ContentTypes[RandomNumbers.Next(ContentTypes.Length)];

	private string _key;

	public override string Id => "BingTranslateLegitimate";

	public override string FriendlyName => "Bing Translator (Authenticated)";

	public override int MaxTranslationsPerRequest => 10;

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-CN":
		case "zh":
			return "zh-Hans";
		case "zh-TW":
			return "zh-Hant";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		_key = context.GetOrCreateSetting<string>("BingLegitimate", "OcpApimSubscriptionKey", "");
		if (string.IsNullOrEmpty(_key))
		{
			throw new EndpointInitializationException("The BingTranslateLegitimate endpoint requires an API key which has not been provided.");
		}
		context.DisableCertificateChecksFor(new string[1] { "api.cognitive.microsofttranslator.com" });
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("[");
		for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++)
		{
			string value = JsonHelper.Escape(((ITranslationContextBase)context).UntranslatedTexts[i]);
			stringBuilder.Append("{\"Text\":\"");
			stringBuilder.Append(value);
			stringBuilder.Append("\"}");
			if (((ITranslationContextBase)context).UntranslatedTexts.Length - 1 != i)
			{
				stringBuilder.Append(",");
			}
		}
		stringBuilder.Append("]");
		XUnityWebRequest val = new XUnityWebRequest("POST", string.Format(HttpsServicePointTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage)), stringBuilder.ToString());
		if (Accept != null)
		{
			val.Headers[HttpRequestHeader.Accept] = Accept;
		}
		if (ContentType != null)
		{
			val.Headers[HttpRequestHeader.ContentType] = ContentType;
		}
		val.Headers["Ocp-Apim-Subscription-Key"] = _key;
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		JSONArray asArray = JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsArray;
		List<string> list = new List<string>();
		for (int i = 0; i < ((JSONNode)asArray).Count; i++)
		{
			JSONNode obj = ((JSONNode)((JSONNode)asArray)[i].AsObject)["translations"];
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				JSONNode obj3 = ((JSONNode)obj.AsArray)[0];
				obj2 = ((obj3 != null) ? ((object)((JSONNode)obj3.AsObject)["text"])?.ToString() : null);
			}
			string text = (string)obj2;
			string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			list.Add(item);
		}
		context.Complete(list.ToArray());
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/CustomTranslate.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Web;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("CustomTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CustomTranslate")]
[assembly: AssemblyTitle("CustomTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CustomTranslate;

internal class CustomTranslateEndpoint : HttpEndpoint
{
	private static readonly string ServicePointTemplateUrl = "{0}?from={1}&to={2}&text={3}";

	private string _endpoint;

	private string _friendlyName;

	public override string Id => "CustomTranslate";

	public override string FriendlyName => _friendlyName;

	public CustomTranslateEndpoint()
	{
		_friendlyName = "Custom";
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		_endpoint = context.GetOrCreateSetting<string>("Custom", "Url", "");
		if (string.IsNullOrEmpty(_endpoint))
		{
			throw new EndpointInitializationException("The custom endpoint requires a url which has not been provided.");
		}
		Uri uri = new Uri(_endpoint);
		context.DisableCertificateChecksFor(new string[1] { uri.Host });
		_friendlyName = _friendlyName + " (" + uri.Host + ")";
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(string.Format(ServicePointTemplateUrl, _endpoint, ((ITranslationContextBase)context).SourceLanguage, ((ITranslationContextBase)context).DestinationLanguage, Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText)));
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		context.Complete(((IHttpResponseInspectionContext)context).Response.Data);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/DeepLTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol;
using XUnity.Common.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("DeepLTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DeepLTranslate")]
[assembly: AssemblyTitle("DeepLTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DeepLTranslate;

public class DeepLTranslate : ExtProtocolEndpoint
{
	private const float MinimumMinDelaySeconds = 1f;

	private const float MinimumMaxDelaySeconds = 3f;

	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"bg", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr",
		"hu", "it", "ja", "lt", "lv", "nl", "pl", "pt", "ro", "ru",
		"sk", "sl", "sv", "zh", "ko"
	};

	public override string Id => "DeepLTranslate";

	public override string FriendlyName => "DeepL Translator";

	public override int MaxConcurrency => 1;

	public override int MaxTranslationsPerRequest => 25;

	protected override string ConfigurationSectionName => "DeepL";

	private string FixLanguage(string lang)
	{
		if (lang == "zh-Hans" || lang == "zh-CN")
		{
			return "zh";
		}
		return lang;
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		((ExtProtocolEndpoint)this).Initialize(context);
		((ExtProtocolEndpoint)this).MinDelay = context.GetOrCreateSetting<float>("DeepL", "MinDelaySeconds", 2f);
		if (((ExtProtocolEndpoint)this).MinDelay < 1f)
		{
			XuaLogger.AutoTranslator.Warn($"[DeepL] Cannot set MinDelaySeconds below {1f} second(s). Setting MinDelaySeconds={1f}");
			context.SetSetting<float>("DeepL", "MinDelaySeconds", 1f);
		}
		((ExtProtocolEndpoint)this).MaxDelay = context.GetOrCreateSetting<float>("DeepL", "MaxDelaySeconds", 6f);
		if (((ExtProtocolEndpoint)this).MaxDelay < 3f)
		{
			XuaLogger.AutoTranslator.Warn($"[DeepL] Cannot set MaxDelaySeconds below {3f} second(s). Setting MaxDelaySeconds={3f}");
			context.SetSetting<float>("DeepL", "MaxDelaySeconds", 3f);
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
		((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("DeepLTranslate.ExtProtocol.ExtDeepLTranslate, DeepLTranslate.ExtProtocol"), Base64FormattingOptions.None);
	}
}
public class DeepLTranslateLegitimate : ExtProtocolEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"bg", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr",
		"hu", "it", "ja", "lt", "lv", "nl", "pl", "pt", "ro", "ru",
		"sk", "sl", "sv", "zh", "ko"
	};

	public override string Id => "DeepLTranslateLegitimate";

	public override string FriendlyName => "DeepL Translator (Authenticated)";

	public override int MaxConcurrency => 1;

	public override int MaxTranslationsPerRequest => 25;

	protected override string ConfigurationSectionName => "DeepLLegitimate";

	private string FixLanguage(string lang)
	{
		if (lang == "zh-Hans" || lang == "zh-CN")
		{
			return "zh";
		}
		return lang;
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		((ExtProtocolEndpoint)this).Initialize(context);
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
		string orCreateSetting = context.GetOrCreateSetting<string>(((ExtProtocolEndpoint)this).ConfigurationSectionName, "ApiKey", "");
		bool orCreateSetting2 = context.GetOrCreateSetting<bool>(((ExtProtocolEndpoint)this).ConfigurationSectionName, "Free", false);
		if (string.IsNullOrEmpty(orCreateSetting))
		{
			throw new EndpointInitializationException("The endpoint requires an API key which has not been provided.");
		}
		((ExtProtocolEndpoint)this).ConfigForExternalProcess = string.Join("\n", orCreateSetting, orCreateSetting2.ToString());
		((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("DeepLTranslate.ExtProtocol.ExtDeepLTranslateLegitimate, DeepLTranslate.ExtProtocol"), Base64FormattingOptions.None);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/ezTransXP.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Win32;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("ezTransXP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ezTransXP")]
[assembly: AssemblyTitle("ezTransXP")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ezTransXP;

public class ezTransXPEndpoint : ExtProtocolEndpoint
{
	public override string Id => "ezTransXP";

	public override string FriendlyName => "ezTransXP";

	public override int MaxConcurrency => 1;

	public override int MaxTranslationsPerRequest => 50;

	public override void Initialize(IInitializationContext context)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		string defaultInstallationPath = GetDefaultInstallationPath();
		string text = context.GetOrCreateSetting<string>("ezTrans", "InstallationPath", defaultInstallationPath);
		if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(defaultInstallationPath))
		{
			context.SetSetting<string>("ezTrans", "InstallationPath", defaultInstallationPath);
			text = defaultInstallationPath;
		}
		context.DisableSpamChecks();
		string text2 = Path.Combine(context.TranslatorDirectory, "FullNET\\ezTransXP.ExtProtocol.exe");
		if (!File.Exists(text2))
		{
			throw new EndpointInitializationException("Could not find any executable at '" + text2 + "'");
		}
		((ExtProtocolEndpoint)this).ExecutablePath = text2;
		((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes(text));
		if (context.SourceLanguage != "ja")
		{
			throw new EndpointInitializationException("Current implementation only supports japanese-to-korean.");
		}
		if (context.DestinationLanguage != "ko")
		{
			throw new EndpointInitializationException("Current implementation only supports japanese-to-korean.");
		}
	}

	public static string GetDefaultInstallationPath()
	{
		try
		{
			return (string)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\ChangShin\\ezTrans", "FilePath", null);
		}
		catch
		{
			return null;
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Common.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using XUnity.AutoTranslator.Plugin.ExtProtocol;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Common.ExtProtocol")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Common.ExtProtocol")]
[assembly: AssemblyTitle("Common.ExtProtocol")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SimpleJSON
{
	public enum JSONNodeType
	{
		Array = 1,
		Object = 2,
		String = 3,
		Number = 4,
		NullValue = 5,
		Boolean = 6,
		None = 7,
		Custom = 255
	}
	public enum JSONTextMode
	{
		Compact,
		Indent
	}
	public abstract class JSONNode
	{
		public struct Enumerator
		{
			private enum Type
			{
				None,
				Array,
				Object
			}

			private Type type;

			private Dictionary<string, JSONNode>.Enumerator m_Object;

			private List<JSONNode>.Enumerator m_Array;

			public bool IsValid => type != Type.None;

			public KeyValuePair<string, JSONNode> Current
			{
				get
				{
					if (type == Type.Array)
					{
						return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
					}
					if (type == Type.Object)
					{
						return m_Object.Current;
					}
					return new KeyValuePair<string, JSONNode>(string.Empty, null);
				}
			}

			public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
			{
				type = Type.Array;
				m_Object = default(Dictionary<string, JSONNode>.Enumerator);
				m_Array = aArrayEnum;
			}

			public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
			{
				type = Type.Object;
				m_Object = aDictEnum;
				m_Array = default(List<JSONNode>.Enumerator);
			}

			public bool MoveNext()
			{
				if (type == Type.Array)
				{
					return m_Array.MoveNext();
				}
				if (type == Type.Object)
				{
					return m_Object.MoveNext();
				}
				return false;
			}
		}

		public struct ValueEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Value;

			public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public ValueEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public ValueEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public struct KeyEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Key;

			public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public KeyEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public KeyEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable
		{
			private JSONNode m_Node;

			private Enumerator m_Enumerator;

			public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current;

			object IEnumerator.Current => m_Enumerator.Current;

			internal LinqEnumerator(JSONNode aNode)
			{
				m_Node = aNode;
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public void Dispose()
			{
				m_Node = null;
				m_Enumerator = default(Enumerator);
			}

			public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}

			public void Reset()
			{
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}
		}

		public static bool forceASCII;

		[ThreadStatic]
		private static StringBuilder m_EscapeBuilder;

		public abstract JSONNodeType Tag { get; }

		public virtual JSONNode this[int aIndex]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual JSONNode this[string aKey]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Value
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual int Count => 0;

		public virtual bool IsNumber => false;

		public virtual bool IsString => false;

		public virtual bool IsBoolean => false;

		public virtual bool IsNull => false;

		public virtual bool IsArray => false;

		public virtual bool IsObject => false;

		public virtual bool Inline
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public virtual IEnumerable<JSONNode> Children
		{
			get
			{
				yield break;
			}
		}

		public IEnumerable<JSONNode> DeepChildren
		{
			get
			{
				foreach (JSONNode child in Children)
				{
					foreach (JSONNode deepChild in child.DeepChildren)
					{
						yield return deepChild;
					}
				}
			}
		}

		public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this);

		public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator());

		public ValueEnumerator Values => new ValueEnumerator(GetEnumerator());

		public virtual double AsDouble
		{
			get
			{
				double result = 0.0;
				if (double.TryParse(Value, out result))
				{
					return result;
				}
				return 0.0;
			}
			set
			{
				Value = value.ToString();
			}
		}

		public virtual int AsInt
		{
			get
			{
				return (int)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual float AsFloat
		{
			get
			{
				return (float)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual bool AsBool
		{
			get
			{
				bool result = false;
				if (bool.TryParse(Value, out result))
				{
					return result;
				}
				return !string.IsNullOrEmpty(Value);
			}
			set
			{
				Value = (value ? "true" : "false");
			}
		}

		public virtual JSONArray AsArray => this as JSONArray;

		public virtual JSONObject AsObject => this as JSONObject;

		internal static StringBuilder EscapeBuilder
		{
			get
			{
				if (m_EscapeBuilder == null)
				{
					m_EscapeBuilder = new StringBuilder();
				}
				return m_EscapeBuilder;
			}
		}

		public virtual void Add(string aKey, JSONNode aItem)
		{
		}

		public virtual void Add(JSONNode aItem)
		{
			Add("", aItem);
		}

		public virtual JSONNode Remove(string aKey)
		{
			return null;
		}

		public virtual JSONNode Remove(int aIndex)
		{
			return null;
		}

		public virtual JSONNode Remove(JSONNode aNode)
		{
			return aNode;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact);
			return stringBuilder.ToString();
		}

		public virtual string ToString(int aIndent)
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent);
			return stringBuilder.ToString();
		}

		internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);

		public abstract Enumerator GetEnumerator();

		public static implicit operator JSONNode(string s)
		{
			return new JSONString(s);
		}

		public static implicit operator string(JSONNode d)
		{
			if (!(d == null))
			{
				return d.Value;
			}
			return null;
		}

		public static implicit operator JSONNode(double n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator double(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsDouble;
			}
			return 0.0;
		}

		public static implicit operator JSONNode(float n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator float(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsFloat;
			}
			return 0f;
		}

		public static implicit operator JSONNode(int n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator int(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsInt;
			}
			return 0;
		}

		public static implicit operator JSONNode(bool b)
		{
			return new JSONBool(b);
		}

		public static implicit operator bool(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsBool;
			}
			return false;
		}

		public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue)
		{
			return aKeyValue.Value;
		}

		public static bool operator ==(JSONNode a, object b)
		{
			if ((object)a == b)
			{
				return true;
			}
			bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator;
			bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator;
			if (flag && flag2)
			{
				return true;
			}
			if (!flag)
			{
				return a.Equals(b);
			}
			return false;
		}

		public static bool operator !=(JSONNode a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		internal static string Escape(string aText)
		{
			StringBuilder escapeBuilder = EscapeBuilder;
			escapeBuilder.Length = 0;
			if (escapeBuilder.Capacity < aText.Length + aText.Length / 10)
			{
				escapeBuilder.Capacity = aText.Length + aText.Length / 10;
			}
			foreach (char c in aText)
			{
				switch (c)
				{
				case '\\':
					escapeBuilder.Append("\\\\");
					continue;
				case '"':
					escapeBuilder.Append("\\\"");
					continue;
				case '\n':
					escapeBuilder.Append("\\n");
					continue;
				case '\r':
					escapeBuilder.Append("\\r");
					continue;
				case '\t':
					escapeBuilder.Append("\\t");
					continue;
				case '\b':
					escapeBuilder.Append("\\b");
					continue;
				case '\f':
					escapeBuilder.Append("\\f");
					continue;
				}
				if (c < ' ' || (forceASCII && c > '\u007f'))
				{
					ushort num = c;
					escapeBuilder.Append("\\u").Append(num.ToString("X4"));
				}
				else
				{
					escapeBuilder.Append(c);
				}
			}
			string result = escapeBuilder.ToString();
			escapeBuilder.Length = 0;
			return result;
		}

		private static void ParseElement(JSONNode ctx, string token, string tokenName, bool quoted)
		{
			if (quoted)
			{
				ctx.Add(tokenName, token);
				return;
			}
			string text = token.ToLower();
			switch (text)
			{
			case "false":
			case "true":
				ctx.Add(tokenName, text == "true");
				return;
			case "null":
				ctx.Add(tokenName, null);
				return;
			}
			if (double.TryParse(token, out var result))
			{
				ctx.Add(tokenName, result);
			}
			else
			{
				ctx.Add(tokenName, token);
			}
		}

		public static JSONNode Parse(string aJSON)
		{
			Stack<JSONNode> stack = new Stack<JSONNode>();
			JSONNode jSONNode = null;
			int i = 0;
			StringBuilder stringBuilder = new StringBuilder();
			string text = "";
			bool flag = false;
			bool flag2 = false;
			for (; i < aJSON.Length; i++)
			{
				switch (aJSON[i])
				{
				case '{':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONObject());
					if (jSONNode != null)
					{
						jSONNode.Add(text, stack.Peek());
					}
					text = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					break;
				case '[':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONArray());
					if (jSONNode != null)
					{
						jSONNode.Add(text, stack.Peek());
					}
					text = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					break;
				case ']':
				case '}':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stack.Count == 0)
					{
						throw new Exception("JSON Parse: Too many closing brackets");
					}
					stack.Pop();
					if (stringBuilder.Length > 0 || flag2)
					{
						ParseElement(jSONNode, stringBuilder.ToString(), text, flag2);
						flag2 = false;
					}
					text = "";
					stringBuilder.Length = 0;
					if (stack.Count > 0)
					{
						jSONNode = stack.Peek();
					}
					break;
				case ':':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					text = stringBuilder.ToString();
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '"':
					flag = !flag;
					flag2 = flag2 || flag;
					break;
				case ',':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stringBuilder.Length > 0 || flag2)
					{
						ParseElement(jSONNode, stringBuilder.ToString(), text, flag2);
						flag2 = false;
					}
					text = "";
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '\t':
				case ' ':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				case '\\':
					i++;
					if (flag)
					{
						char c = aJSON[i];
						switch (c)
						{
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'u':
						{
							string s = aJSON.Substring(i + 1, 4);
							stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier));
							i += 4;
							break;
						}
						default:
							stringBuilder.Append(c);
							break;
						}
					}
					break;
				default:
					stringBuilder.Append(aJSON[i]);
					break;
				case '\n':
				case '\r':
					break;
				}
			}
			if (flag)
			{
				throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
			}
			return jSONNode;
		}
	}
	public class JSONArray : JSONNode
	{
		private List<JSONNode> m_List = new List<JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Array;

		public override bool IsArray => true;

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					return new JSONLazyCreator(this);
				}
				return m_List[aIndex];
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					m_List.Add(value);
				}
				else
				{
					m_List[aIndex] = value;
				}
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				m_List.Add(value);
			}
		}

		public override int Count => m_List.Count;

		public override IEnumerable<JSONNode> Children
		{
			get
			{
				foreach (JSONNode item in m_List)
				{
					yield return item;
				}
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_List.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			m_List.Add(aItem);
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_List.Count)
			{
				return null;
			}
			JSONNode result = m_List[aIndex];
			m_List.RemoveAt(aIndex);
			return result;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			m_List.Remove(aNode);
			return aNode;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('[');
			int count = m_List.Count;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			for (int i = 0; i < count; i++)
			{
				if (i > 0)
				{
					aSB.Append(',');
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append(']');
		}
	}
	public class JSONObject : JSONNode
	{
		private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Object;

		public override bool IsObject => true;

		public override JSONNode this[string aKey]
		{
			get
			{
				if (m_Dict.ContainsKey(aKey))
				{
					return m_Dict[aKey];
				}
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = value;
				}
				else
				{
					m_Dict.Add(aKey, value);
				}
			}
		}

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_Dict.Count)
				{
					return null;
				}
				return m_Dict.ElementAt(aIndex).Value;
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex >= 0 && aIndex < m_Dict.Count)
				{
					string key = m_Dict.ElementAt(aIndex).Key;
					m_Dict[key] = value;
				}
			}
		}

		public override int Count => m_Dict.Count;

		public override IEnumerable<JSONNode> Children
		{
			get
			{
				foreach (KeyValuePair<string, JSONNode> item in m_Dict)
				{
					yield return item.Value;
				}
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_Dict.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			if (!string.IsNullOrEmpty(aKey))
			{
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = aItem;
				}
				else
				{
					m_Dict.Add(aKey, aItem);
				}
			}
			else
			{
				m_Dict.Add(Guid.NewGuid().ToString(), aItem);
			}
		}

		public override JSONNode Remove(string aKey)
		{
			if (!m_Dict.ContainsKey(aKey))
			{
				return null;
			}
			JSONNode result = m_Dict[aKey];
			m_Dict.Remove(aKey);
			return result;
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_Dict.Count)
			{
				return null;
			}
			KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex);
			m_Dict.Remove(keyValuePair.Key);
			return keyValuePair.Value;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			try
			{
				KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First();
				m_Dict.Remove(keyValuePair.Key);
				return aNode;
			}
			catch
			{
				return null;
			}
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('{');
			bool flag = true;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				if (!flag)
				{
					aSB.Append(',');
				}
				flag = false;
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"');
				if (aMode == JSONTextMode.Compact)
				{
					aSB.Append(':');
				}
				else
				{
					aSB.Append(" : ");
				}
				item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append('}');
		}
	}
	public class JSONString : JSONNode
	{
		private string m_Data;

		public override JSONNodeType Tag => JSONNodeType.String;

		public override bool IsString => true;

		public override string Value
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONString(string aData)
		{
			m_Data = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"');
		}

		public override bool Equals(object obj)
		{
			if (base.Equals(obj))
			{
				return true;
			}
			if (obj is string text)
			{
				return m_Data == text;
			}
			JSONString jSONString = obj as JSONString;
			if (jSONString != null)
			{
				return m_Data == jSONString.m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONNumber : JSONNode
	{
		private double m_Data;

		public override JSONNodeType Tag => JSONNodeType.Number;

		public override bool IsNumber => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (double.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override double AsDouble
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONNumber(double aData)
		{
			m_Data = aData;
		}

		public JSONNumber(string aData)
		{
			Value = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data);
		}

		private static bool IsNumeric(object value)
		{
			if (!(value is int) && !(value is uint) && !(value is float) && !(value is double) && !(value is decimal) && !(value is long) && !(value is ulong) && !(value is short) && !(value is ushort) && !(value is sbyte))
			{
				return value is byte;
			}
			return true;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (base.Equals(obj))
			{
				return true;
			}
			JSONNumber jSONNumber = obj as JSONNumber;
			if (jSONNumber != null)
			{
				return m_Data == jSONNumber.m_Data;
			}
			if (IsNumeric(obj))
			{
				return Convert.ToDouble(obj) == m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONBool : JSONNode
	{
		private bool m_Data;

		public override JSONNodeType Tag => JSONNodeType.Boolean;

		public override bool IsBoolean => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (bool.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONBool(bool aData)
		{
			m_Data = aData;
		}

		public JSONBool(string aData)
		{
			Value = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data ? "true" : "false");
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is bool)
			{
				return m_Data == (bool)obj;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONNull : JSONNode
	{
		private static JSONNull m_StaticInstance = new JSONNull();

		public static bool reuseSameInstance = true;

		public override JSONNodeType Tag => JSONNodeType.NullValue;

		public override bool IsNull => true;

		public override string Value
		{
			get
			{
				return "null";
			}
			set
			{
			}
		}

		public override bool AsBool
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public static JSONNull CreateOrGet()
		{
			if (reuseSameInstance)
			{
				return m_StaticInstance;
			}
			return new JSONNull();
		}

		private JSONNull()
		{
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public override bool Equals(object obj)
		{
			if ((object)this == obj)
			{
				return true;
			}
			return obj is JSONNull;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	internal class JSONLazyCreator : JSONNode
	{
		private JSONNode m_Node;

		private string m_Key;

		public override JSONNodeType Tag => JSONNodeType.None;

		public override JSONNode this[int aIndex]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				JSONArray jSONArray = new JSONArray();
				jSONArray.Add(value);
				Set(jSONArray);
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				JSONObject jSONObject = new JSONObject();
				jSONObject.Add(aKey, value);
				Set(jSONObject);
			}
		}

		public override int AsInt
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override float AsFloat
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0f;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override double AsDouble
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0.0;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override bool AsBool
		{
			get
			{
				JSONBool aVal = new JSONBool(aData: false);
				Set(aVal);
				return false;
			}
			set
			{
				JSONBool aVal = new JSONBool(value);
				Set(aVal);
			}
		}

		public override JSONArray AsArray
		{
			get
			{
				JSONArray jSONArray = new JSONArray();
				Set(jSONArray);
				return jSONArray;
			}
		}

		public override JSONObject AsObject
		{
			get
			{
				JSONObject jSONObject = new JSONObject();
				Set(jSONObject);
				return jSONObject;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONLazyCreator(JSONNode aNode)
		{
			m_Node = aNode;
			m_Key = null;
		}

		public JSONLazyCreator(JSONNode aNode, string aKey)
		{
			m_Node = aNode;
			m_Key = aKey;
		}

		private void Set(JSONNode aVal)
		{
			if (m_Key == null)
			{
				m_Node.Add(aVal);
			}
			else
			{
				m_Node.Add(m_Key, aVal);
			}
			m_Node = null;
		}

		public override void Add(JSONNode aItem)
		{
			JSONArray jSONArray = new JSONArray();
			jSONArray.Add(aItem);
			Set(jSONArray);
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			JSONObject jSONObject = new JSONObject();
			jSONObject.Add(aKey, aItem);
			Set(jSONObject);
		}

		public static bool operator ==(JSONLazyCreator a, object b)
		{
			if (b == null)
			{
				return true;
			}
			return (object)a == b;
		}

		public static bool operator !=(JSONLazyCreator a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return true;
			}
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	public static class JSON
	{
		public static JSONNode Parse(string aJSON)
		{
			return JSONNode.Parse(aJSON);
		}
	}
}
namespace Common.ExtProtocol
{
	public interface IExtTranslateEndpoint
	{
		Task Translate(ITranslationContext context);

		void Initialize(string config);
	}
	public interface ITranslationContext : ITranslationContextBase
	{
		void Complete(string translatedText);

		void Complete(string[] translatedTexts);
	}
	public interface ITranslationContextBase
	{
		string UntranslatedText { get; }

		string[] UntranslatedTexts { get; }

		UntranslatedTextInfo UntranslatedTextInfo { get; }

		UntranslatedTextInfo[] UntranslatedTextInfos { get; }

		string SourceLanguage { get; }

		string DestinationLanguage { get; }

		object UserState { get; set; }

		void Fail(string reason, Exception exception);

		void Fail(string reason);
	}
	public class TranslationContext : ITranslationContext, ITranslationContextBase
	{
		private string[] _untranslatedTexts;

		public string UntranslatedText => UntranslatedTexts[0];

		public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((UntranslatedTextInfo x) => x.UntranslatedText).ToArray());

		public UntranslatedTextInfo UntranslatedTextInfo => UntranslatedTextInfos[0];

		public UntranslatedTextInfo[] UntranslatedTextInfos { get; }

		public string SourceLanguage { get; }

		public string DestinationLanguage { get; }

		internal bool IsDone { get; private set; }

		public string[] TranslatedTexts { get; private set; }

		public string ErrorMessage { get; private set; }

		public Exception Error { get; private set; }

		public object UserState { get; set; }

		public TranslationContext(TransmittableUntranslatedTextInfo[] untranslatedTexts, string sourceLanguage, string destinationLanguage)
		{
			UntranslatedTextInfos = untranslatedTexts.Select((TransmittableUntranslatedTextInfo x) => new UntranslatedTextInfo(x)).ToArray();
			SourceLanguage = sourceLanguage;
			DestinationLanguage = destinationLanguage;
		}

		public void Complete(string translatedText)
		{
			Complete(new string[1] { translatedText });
		}

		public void Complete(string[] translatedTexts)
		{
			if (IsDone)
			{
				return;
			}
			try
			{
				if (translatedTexts.Length == 0)
				{
					FailContext("Received empty translation from translator.", null);
					return;
				}
				for (int i = 0; i < translatedTexts.Length; i++)
				{
					if (string.IsNullOrEmpty(translatedTexts[0]))
					{
						FailContext("Received empty translation from translator.", null);
						return;
					}
				}
				CompleteContext(translatedTexts);
			}
			finally
			{
				IsDone = true;
			}
		}

		public void Fail(string reason, Exception exception)
		{
			if (IsDone)
			{
				return;
			}
			try
			{
				FailContext(reason, exception);
				throw new TranslationContextException();
			}
			finally
			{
				IsDone = true;
			}
		}

		public void Fail(string reason)
		{
			if (IsDone)
			{
				return;
			}
			try
			{
				FailContext(reason, null);
				throw new TranslationContextException();
			}
			finally
			{
				IsDone = true;
			}
		}

		public void FailWithoutThrowing(string reason, Exception exception)
		{
			if (IsDone)
			{
				return;
			}
			try
			{
				FailContext(reason, exception);
			}
			finally
			{
				IsDone = true;
			}
		}

		internal void FailIfNotCompleted()
		{
			if (!IsDone)
			{
				FailWithoutThrowing("The translation request was not completed before returning from translator.", null);
			}
		}

		public void FailContext(string reason, Exception exception)
		{
			ErrorMessage = reason;
			Error = exception;
		}

		public void CompleteContext(string[] translatedTexts)
		{
			TranslatedTexts = translatedTexts;
		}
	}
	[Serializable]
	internal class TranslationContextException : Exception
	{
		public TranslationContextException()
		{
		}

		public TranslationContextException(string message)
			: base(message)
		{
		}

		public TranslationContextException(string message, Exception inner)
			: base(message, inner)
		{
		}

		protected TranslationContextException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	public class UntranslatedTextInfo
	{
		public string[] ContextBefore { get; }

		public string UntranslatedText { get; }

		public string[] ContextAfter { get; }

		public UntranslatedTextInfo(TransmittableUntranslatedTextInfo untranslatedTextInfo)
		{
			ContextBefore = untranslatedTextInfo.ContextBefore;
			UntranslatedText = untranslatedTextInfo.UntranslatedText;
			ContextAfter = untranslatedTextInfo.ContextAfter;
		}

		public UntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter)
		{
			ContextBefore = contextBefore;
			UntranslatedText = untranslatedText;
			ContextAfter = contextAfter;
		}
	}
}
namespace Common.ExtProtocol.Utilities
{
	public static class JsonHelper
	{
		public static string Unescape(string str)
		{
			if (str == null)
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder(str);
			bool flag = false;
			for (int i = 0; i < stringBuilder.Length; i++)
			{
				char c = stringBuilder[i];
				if (flag)
				{
					bool flag2 = true;
					char c2 = '\0';
					switch (c)
					{
					case 'b':
						c2 = '\b';
						break;
					case 'f':
						c2 = '\f';
						break;
					case 'n':
						c2 = '\n';
						break;
					case 'r':
						c2 = '\r';
						break;
					case 't':
						c2 = '\t';
						break;
					case '"':
						c2 = '"';
						break;
					case '\\':
						c2 = '\\';
						break;
					case 'u':
						c2 = 'u';
						break;
					default:
						flag2 = false;
						break;
					}
					if (flag2)
					{
						if (c2 == 'u')
						{
							char value = (char)int.Parse(new string(new char[4]
							{
								stringBuilder[i + 1],
								stringBuilder[i + 2],
								stringBuilder[i + 3],
								stringBuilder[i + 4]
							}), NumberStyles.HexNumber);
							stringBuilder.Remove(--i, 6);
							stringBuilder.Insert(i, value);
						}
						else
						{
							stringBuilder.Remove(--i, 2);
							stringBuilder.Insert(i, c2);
						}
					}
					flag = false;
				}
				else if (c == '\\')
				{
					flag = true;
				}
			}
			return stringBuilder.ToString();
		}

		public static string Escape(string str)
		{
			if (str == null || str.Length == 0)
			{
				return "";
			}
			int length = str.Length;
			StringBuilder stringBuilder = new StringBuilder(length + 4);
			for (int i = 0; i < length; i++)
			{
				char c = str[i];
				switch (c)
				{
				case '"':
				case '\\':
					stringBuilder.Append('\\');
					stringBuilder.Append(c);
					break;
				case '\b':
					stringBuilder.Append("\\b");
					break;
				case '\t':
					stringBuilder.Append("\\t");
					break;
				case '\n':
					stringBuilder.Append("\\n");
					break;
				case '\f':
					stringBuilder.Append("\\f");
					break;
				case '\r':
					stringBuilder.Append("\\r");
					break;
				case '\u0085':
					stringBuilder.Append("\\u0085");
					break;
				case '\u2028':
					stringBuilder.Append("\\u2028");
					break;
				case '\u2029':
					stringBuilder.Append("\\u2029");
					break;
				default:
					stringBuilder.Append(c);
					break;
				}
			}
			return stringBuilder.ToString();
		}
	}
	public static class StringBuilderExtensions
	{
		public static bool EndsWithWhitespaceOrNewline(this StringBuilder builder)
		{
			if (builder.Length == 0)
			{
				return true;
			}
			char c = builder[builder.Length - 1];
			if (!char.IsWhiteSpace(c))
			{
				return c == '\n';
			}
			return true;
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/DeepLTranslate.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Common.ExtProtocol;
using Common.ExtProtocol.Utilities;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SimpleJSON;

[assembly: AssemblyProduct("DeepLTranslate.ExtProtocol")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("DeepLTranslate.ExtProtocol")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyTitle("DeepLTranslate.ExtProtocol")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DeepLTranslate.ExtProtocol
{
	[Serializable]
	public class BlockedException : Exception
	{
		public BlockedException()
		{
		}

		public BlockedException(string message)
			: base(message)
		{
		}

		public BlockedException(string message, Exception inner)
			: base(message, inner)
		{
		}

		protected BlockedException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	public static class HttpResponseMessageExtensions
	{
		public static void ThrowIfBlocked(this HttpResponseMessage msg)
		{
			if (msg.StatusCode == HttpStatusCode.TooManyRequests)
			{
				throw new Exception("Too many requests!");
			}
		}
	}
	public class ExtDeepLTranslate : IExtTranslateEndpoint
	{
		private class UntranslatedTextInfo
		{
			public string UntranslatedText { get; set; }

			public List<TranslationPart> TranslationParts { get; set; }
		}

		public class TranslationPart
		{
			public bool IsTranslatable { get; set; }

			public string Value { get; set; }
		}

		private static readonly Regex NewlineSplitter;

		private static readonly DateTime Epoch;

		private static readonly string HttpsServicePointTemplateUrl;

		private static readonly string HttpsTranslateUserSite;

		private static readonly string HttpsTranslateStateSetup;

		private static readonly Random RandomNumbers;

		private static readonly string[] Accepts;

		private static readonly string[] AcceptLanguages;

		private static readonly string[] Referers;

		private static readonly string[] Origins;

		private static readonly string Accept;

		private static readonly string AcceptLanguage;

		private static readonly string Referer;

		private static readonly string Origin;

		private SemaphoreSlim _sem;

		private HttpClient _client;

		private HttpClientHandler _handler;

		private bool _hasSetup;

		private int _translationCount;

		private int _resetAfter = RandomNumbers.Next(75, 125);

		private long _id;

		static ExtDeepLTranslate()
		{
			NewlineSplitter = new Regex("([\\s]*[\\r\\n]+[\\s]*)");
			Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
			HttpsServicePointTemplateUrl = "https://www2.deepl.com/jsonrpc";
			HttpsTranslateUserSite = "https://www.deepl.com/translator";
			HttpsTranslateStateSetup = "https://www.deepl.com/PHP/backend/clientState.php?request_type=jsonrpc&il=EN";
			RandomNumbers = new Random();
			Accepts = new string[1] { "*/*" };
			AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" };
			Referers = new string[1] { "https://www.deepl.com/translator" };
			Origins = new string[1] { "https://www.deepl.com" };
			Accept = Accepts[RandomNumbers.Next(Accepts.Length)];
			AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)];
			Referer = Referers[RandomNumbers.Next(Referers.Length)];
			Origin = Origins[RandomNumbers.Next(Origins.Length)];
			ServicePointManager.SecurityProtocol |= SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
		}

		public ExtDeepLTranslate()
		{
			_sem = new SemaphoreSlim(1, 1);
		}

		public void Initialize(string config)
		{
		}

		public void Reset()
		{
			_hasSetup = false;
		}

		private void CreateClientAndHandler()
		{
			if (_client != null)
			{
				_client.Dispose();
			}
			_handler = new HttpClientHandler();
			_handler.CookieContainer = new CookieContainer();
			_handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
			_client = new HttpClient(_handler, disposeHandler: true);
			_client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36");
		}

		private static string FixLanguage(string lang)
		{
			if (lang == "zh-Hans" || lang == "zh-CN")
			{
				return "zh";
			}
			return lang;
		}

		public async Task EnsureSetupState()
		{
			if (!_hasSetup || _translationCount % _resetAfter == 0)
			{
				_resetAfter = RandomNumbers.Next(75, 125);
				_hasSetup = true;
				_id = 10000 * (long)(10000.0 * RandomNumbers.NextDouble());
				CreateClientAndHandler();
				await SetupState();
			}
		}

		public async Task SetupState()
		{
			_translationCount = 0;
			await RequestWebsite();
			await GetClientState();
		}

		private void AddHeaders(HttpRequestMessage request, HttpContent content, bool isTranslationRequest)
		{
			if (AcceptLanguage != null)
			{
				request.Headers.TryAddWithoutValidation("Accept-Language", AcceptLanguage);
			}
			if (Accept != null)
			{
				request.Headers.TryAddWithoutValidation("Accept", Accept);
			}
			if (Referer != null && isTranslationRequest)
			{
				request.Headers.TryAddWithoutValidation("Referer", Referer);
			}
			if (Origin != null && isTranslationRequest)
			{
				request.Headers.TryAddWithoutValidation("Origin", Origin);
			}
			if (isTranslationRequest && content != null)
			{
				content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
			}
			request.Headers.TryAddWithoutValidation("DNT", "1");
		}

		public async Task Translate(ITranslationContext context)
		{
			_ = 3;
			try
			{
				await _sem.WaitAsync();
				await EnsureSetupState();
				_translationCount++;
				_id++;
				long num = (long)(DateTime.UtcNow - Epoch).TotalMilliseconds;
				long num2 = 1L;
				StringBuìlder stringBuìlder = new StringBuìlder();
				stringBuìlder.Append("{\"jsonrpc\":\"2.0\",\"method\":\"LMT_handle_jobs\",\"params\":{\"jobs\":[");
				List<UntranslatedTextInfo> untranslatedTextInfos = new List<UntranslatedTextInfo>();
				UntranslatedTextInfo[] untranslatedTextInfos2 = ((ITranslationContextBase)context).UntranslatedTextInfos;
				foreach (UntranslatedTextInfo val in untranslatedTextInfos2)
				{
					List<TranslationPart> list = (from x in NewlineSplitter.Split(val.UntranslatedText)
						select new TranslationPart
						{
							Value = x,
							IsTranslatable = !NewlineSplitter.IsMatch(x)
						}).ToList();
					string[] array = (from x in list
						where x.IsTranslatable
						select x.Value).ToArray();
					for (int j = 0; j < array.Length; j++)
					{
						string text = array[j];
						stringBuìlder.Append("{\"kind\":\"default\",\"preferred_num_beams\":1,\"raw_en_sentence\":\"");
						stringBuìlder.Append(JsonHelper.Escape(text));
						HashSet<string> hashSet = new HashSet<string>();
						stringBuìlder.Append("\",\"raw_en_context_before\":[");
						bool flag = false;
						string[] contextBefore = val.ContextBefore;
						foreach (string text2 in contextBefore)
						{
							if (!hashSet.Contains(text2))
							{
								stringBuìlder.Append("\"");
								stringBuìlder.Append(JsonHelper.Escape(text2));
								stringBuìlder.Append("\"");
								stringBuìlder.Append(",");
								flag = true;
							}
						}
						for (int l = 0; l < j; l++)
						{
							if (!hashSet.Contains(array[l]))
							{
								stringBuìlder.Append("\"");
								stringBuìlder.Append(JsonHelper.Escape(array[l]));
								stringBuìlder.Append("\"");
								stringBuìlder.Append(",");
								flag = true;
							}
						}
						if (flag)
						{
							stringBuìlder.Remove(stringBuìlder.Length - 1, 1);
						}
						stringBuìlder.Append("],\"raw_en_context_after\":[");
						bool flag2 = false;
						for (int m = j + 1; m < array.Length; m++)
						{
							if (!hashSet.Contains(array[m]))
							{
								stringBuìlder.Append("\"");
								stringBuìlder.Append(JsonHelper.Escape(array[m]));
								stringBuìlder.Append("\"");
								stringBuìlder.Append(",");
								flag2 = true;
							}
						}
						contextBefore = val.ContextAfter;
						foreach (string text3 in contextBefore)
						{
							if (!hashSet.Contains(text3))
							{
								stringBuìlder.Append("\"");
								stringBuìlder.Append(JsonHelper.Escape(text3));
								stringBuìlder.Append("\"");
								stringBuìlder.Append(",");
								flag2 = true;
							}
						}
						if (flag2)
						{
							stringBuìlder.Remove(stringBuìlder.Length - 1, 1);
						}
						stringBuìlder.Append("]},");
						num2 += text.Count((char c) => c == 'i');
					}
					untranslatedTextInfos.Add(new UntranslatedTextInfo
					{
						TranslationParts = list,
						UntranslatedText = val.UntranslatedText
					});
				}
				stringBuìlder.Remove(stringBuìlder.Length - 1, 1);
				long num3 = num + (num2 - num % num2);
				stringBuìlder.Append("],\"lang\":{\"user_preferred_langs\":[\"");
				stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant());
				stringBuìlder.Append("\",\"");
				stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant());
				stringBuìlder.Append("\"],\"source_lang_user_selected\":\"");
				stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant());
				stringBuìlder.Append("\",\"target_lang\":\"");
				stringBuìlder.Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant());
				stringBuìlder.Append("\"},\"priority\":-1,\"timestamp\":");
				stringBuìlder.Append(num3.ToString(CultureInfo.InvariantCulture));
				stringBuìlder.Append("},\"id\":");
				stringBuìlder.Append(_id);
				stringBuìlder.Append("}");
				StringContent content = new StringContent(stringBuìlder.ToString());
				using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, HttpsServicePointTemplateUrl);
				AddHeaders(request, content, isTranslationRequest: true);
				using HttpResponseMessage response = await _client.PostAsync(HttpsServicePointTemplateUrl, content);
				response.ThrowIfBlocked();
				response.EnsureSuccessStatusCode();
				ExtractTranslation(await response.Content.ReadAsStringAsync(), untranslatedTextInfos, context);
			}
			catch (BlockedException)
			{
				Reset();
				throw;
			}
			finally
			{
				_sem.Release();
			}
		}

		private void ExtractTranslation(string data, List<UntranslatedTextInfo> untranslatedTextInfos, ITranslationContext context)
		{
			JSONArray asArray = JSON.Parse(data)["result"]["translations"].AsArray;
			List<string> list = new List<string>();
			int num = 0;
			for (int i = 0; i < untranslatedTextInfos.Count; i++)
			{
				List<TranslationPart> translationParts = untranslatedTextInfos[i].TranslationParts;
				StringBuilder stringBuilder = new StringBuilder();
				foreach (TranslationPart item in translationParts)
				{
					if (item.IsTranslatable)
					{
						JSONArray asArray2 = ((JSONNode)asArray)[num++]["beams"].AsArray;
						if (((JSONNode)asArray2).Count > 0)
						{
							string text = ((object)((JSONNode)asArray2)[0]["postprocessed_sentence"]).ToString();
							string value = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
							stringBuilder.Append(value);
						}
					}
					else
					{
						stringBuilder.Append(item.Value);
					}
				}
				string text2 = stringBuilder.ToString();
				if (string.IsNullOrWhiteSpace(text2))
				{
					throw new Exception("Found no valid translations in beam!");
				}
				list.Add(text2);
			}
			context.Complete(list.ToArray());
		}

		public async Task RequestWebsite()
		{
			using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, HttpsTranslateUserSite);
			AddHeaders(request, null, isTranslationRequest: false);
			using HttpResponseMessage response = await _client.SendAsync(request);
			response.ThrowIfBlocked();
			response.EnsureSuccessStatusCode();
			await response.Content.ReadAsStringAsync();
		}

		public async Task GetClientState()
		{
			_id++;
			StringBuìlder stringBuìlder = new StringBuìlder();
			stringBuìlder.Append("{\"jsonrpc\":\"2.0\",\"method\":\"getClientState\",\"params\":{\"v\":\"20180814\"},\"id\":");
			stringBuìlder.Append(_id);
			stringBuìlder.Append("}");
			StringContent content = new StringContent(stringBuìlder.ToString());
			using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, HttpsTranslateStateSetup);
			AddHeaders(request, content, isTranslationRequest: false);
			using HttpResponseMessage response = await _client.SendAsync(request);
			response.ThrowIfBlocked();
			response.EnsureSuccessStatusCode();
			await response.Content.ReadAsStringAsync();
		}

		public void Dispose()
		{
			_client?.Dispose();
		}
	}
	public class ExtDeepLTranslateLegitimate : IExtTranslateEndpoint
	{
		private class UntranslatedTextInfo
		{
			public string UntranslatedText { get; set; }

			public List<TranslationPart> TranslationParts { get; set; }
		}

		public class TranslationPart
		{
			public bool IsTranslatable { get; set; }

			public string Value { get; set; }
		}

		private class TranslationResponse
		{
			public List<Translation> translations { get; set; }
		}

		private class Translation
		{
			public string detected_source_language { get; set; }

			public string text { get; set; }
		}

		private string _httpsServicePointTemplateUrl = "https://api.deepl.com/v2/translate?auth_key={0}";

		private HttpClient _client;

		private HttpClientHandler _handler;

		private string _apiKey;

		static ExtDeepLTranslateLegitimate()
		{
			ServicePointManager.SecurityProtocol |= SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
		}

		public ExtDeepLTranslateLegitimate()
		{
			CreateClientAndHandler();
		}

		public void Initialize(string config)
		{
			string[] array = config.Split(new char[1] { '\n' }, StringSplitOptions.None);
			_apiKey = array[0];
			if (string.Equals(array[1], "true", StringComparison.OrdinalIgnoreCase))
			{
				_httpsServicePointTemplateUrl = "https://api-free.deepl.com/v2/translate?auth_key={0}";
			}
			else
			{
				_httpsServicePointTemplateUrl = "https://api.deepl.com/v2/translate?auth_key={0}";
			}
		}

		private void CreateClientAndHandler()
		{
			if (_client != null)
			{
				_client.Dispose();
			}
			_handler = new HttpClientHandler();
			_handler.CookieContainer = new CookieContainer();
			_handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
			_client = new HttpClient(_handler, disposeHandler: true);
			_client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("XUnity", "5.3.0"));
			_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
		}

		private static string FixLanguage(string lang)
		{
			if (lang == "zh-Hans" || lang == "zh-CN")
			{
				return "zh";
			}
			return lang;
		}

		public async Task Translate(ITranslationContext context)
		{
			List<UntranslatedTextInfo> untranslatedTextInfos = new List<UntranslatedTextInfo>();
			List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
			list.Add(new KeyValuePair<string, string>("auth_key", _apiKey));
			list.Add(new KeyValuePair<string, string>("source_lang", FixLanguage(((ITranslationContextBase)context).SourceLanguage).ToUpperInvariant()));
			list.Add(new KeyValuePair<string, string>("target_lang", FixLanguage(((ITranslationContextBase)context).DestinationLanguage).ToUpperInvariant()));
			list.Add(new KeyValuePair<string, string>("split_sentences", "1"));
			UntranslatedTextInfo[] untranslatedTextInfos2 = ((ITranslationContextBase)context).UntranslatedTextInfos;
			foreach (UntranslatedTextInfo val in untranslatedTextInfos2)
			{
				list.Add(new KeyValuePair<string, string>("text", val.UntranslatedText));
				untranslatedTextInfos.Add(new UntranslatedTextInfo
				{
					TranslationParts = new List<TranslationPart>
					{
						new TranslationPart
						{
							IsTranslatable = true,
							Value = val.UntranslatedText
						}
					},
					UntranslatedText = val.UntranslatedText
				});
			}
			FormUrlEncodedContent content = new FormUrlEncodedContent(list);
			using (new HttpRequestMessage(HttpMethod.Post, _httpsServicePointTemplateUrl))
			{
				using HttpResponseMessage response = await _client.PostAsync(string.Format(_httpsServicePointTemplateUrl, _apiKey), content);
				response.ThrowIfBlocked();
				response.EnsureSuccessStatusCode();
				ExtractTranslation(await response.Content.ReadAsStringAsync(), untranslatedTextInfos, context);
			}
		}

		private void ExtractTranslation(string data, List<UntranslatedTextInfo> untranslatedTextInfos, ITranslationContext context)
		{
			TranslationResponse translationResponse = JsonConvert.DeserializeObject<TranslationResponse>(data);
			List<string> list = new List<string>();
			int num = 0;
			for (int i = 0; i < untranslatedTextInfos.Count; i++)
			{
				List<TranslationPart> translationParts = untranslatedTextInfos[i].TranslationParts;
				StringBuilder stringBuilder = new StringBuilder();
				foreach (TranslationPart item in translationParts)
				{
					if (item.IsTranslatable)
					{
						string text = translationResponse.translations[num++].text;
						stringBuilder.Append(text);
					}
					else
					{
						stringBuilder.Append(item.Value);
					}
				}
				string text2 = stringBuilder.ToString();
				if (string.IsNullOrWhiteSpace(text2))
				{
					throw new Exception("Found no valid translations in beam!");
				}
				list.Add(text2);
			}
			context.Complete(list.ToArray());
		}

		public void Dispose()
		{
			_client?.Dispose();
		}
	}
}
namespace System.Text
{
	internal class StringBuìlder
	{
		private StringBuilder _builder;

		private long _l;

		public int Length => _builder.Length;

		public StringBuìlder()
		{
			_builder = new StringBuilder();
		}

		public StringBuìlder Append(string str)
		{
			_builder.Append(str);
			return this;
		}

		public StringBuìlder Append(char c)
		{
			_builder.Append(c);
			return this;
		}

		public StringBuìlder Append(int i)
		{
			_builder.Append(i);
			return this;
		}

		public StringBuìlder Append(long l)
		{
			_builder.Append(l);
			_l = l;
			return this;
		}

		public StringBuìlder Remove(int startIndex, int length)
		{
			_builder.Remove(startIndex, length);
			return this;
		}

		public override string ToString()
		{
			return _builder.ToString().Replace("hod\":\"", ((_l + 3) % 13 == 0L || (_l + 5) % 29 == 0L) ? "hod\" : \"" : "hod\": \"");
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/GoogleTranslateCompat.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using Common.ExtProtocol;
using Common.ExtProtocol.Utilities;
using Http.ExtProtocol;
using SimpleJSON;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("GoogleTranslateCompat.ExtProtocol")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GoogleTranslateCompat.ExtProtocol")]
[assembly: AssemblyTitle("GoogleTranslateCompat.ExtProtocol")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GoogleTranslateCompat.ExtProtocol;

internal class GoogleTranslateCompatTranslate : ExtHttpEndpoint
{
	public static readonly string UserAgent_Chrome_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36";

	private static readonly string HttpsServicePointTranslateTemplateUrl = "https://translate.googleapis.com/translate_a/single?client=webapp&sl={0}&tl={1}&dt=t&tk={2}&q={3}";

	private static readonly string HttpsTranslateUserSite = "https://translate.google.com";

	private static readonly Random RandomNumbers = new Random();

	private static readonly string[] Accepts = new string[3] { null, "*/*", "application/json" };

	private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" };

	private static readonly string[] Referers = new string[2] { null, "https://translate.google.com/" };

	private static readonly string[] AcceptCharsets = new string[2]
	{
		null,
		Encoding.UTF8.WebName
	};

	private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)];

	private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)];

	private static readonly string Referer = Referers[RandomNumbers.Next(Referers.Length)];

	private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)];

	private CookieContainer _cookieContainer;

	private bool _hasSetup;

	private long m = 427761L;

	private long s = 1179739010L;

	private int _translationCount;

	private int _resetAfter = RandomNumbers.Next(75, 125);

	public GoogleTranslateCompatTranslate()
	{
		_cookieContainer = new CookieContainer();
	}

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override async Task OnBeforeTranslate(IHttpTranslationContext context)
	{
		if (!_hasSetup || _translationCount % _resetAfter == 0)
		{
			_resetAfter = RandomNumbers.Next(75, 125);
			_translationCount = 1;
			_hasSetup = true;
			await SetupTKK();
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		_translationCount++;
		string text = string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts);
		XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpsServicePointTranslateTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Tk(text), Uri.EscapeDataString(text)));
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: true);
		context.Complete(val);
	}

	public override void OnInspectResponse(IHttpResponseInspectionContext context)
	{
		InspectResponse(context.Response);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		string data = ((IHttpResponseInspectionContext)context).Response.Data;
		JSONNode val = JSON.Parse(data);
		StringBuilder stringBuilder = new StringBuilder(data.Length);
		val = ((JSONNode)val.AsArray)[0];
		if (val.IsNull)
		{
			context.Complete(((ITranslationContextBase)context).UntranslatedText);
			return;
		}
		Enumerator enumerator = ((JSONNode)val.AsArray).GetEnumerator();
		while (((Enumerator)(ref enumerator)).MoveNext())
		{
			string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray)[0]).ToString();
			text = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder))
			{
				stringBuilder.Append('\n');
			}
			stringBuilder.Append(text);
		}
		string text2 = stringBuilder.ToString();
		if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1)
		{
			context.Complete(text2);
			return;
		}
		string[] array = text2.Split(new char[1] { '\n' });
		List<string> list = new List<string>();
		int num = 0;
		string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts;
		for (int i = 0; i < untranslatedTexts.Length; i++)
		{
			int num2 = untranslatedTexts[i].Split(new char[1] { '\n' }).Length;
			string text3 = string.Empty;
			for (int j = 0; j < num2; j++)
			{
				if (num >= array.Length)
				{
					((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
				}
				string text4 = array[num++];
				text3 += text4;
				if (j != num2 - 1)
				{
					text3 += "\n";
				}
			}
			list.Add(text3);
		}
		if (num != array.Length)
		{
			((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
		}
		context.Complete(list.ToArray());
	}

	private XUnityWebRequest CreateWebSiteRequest()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(HttpsTranslateUserSite);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: false);
		return val;
	}

	private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest)
	{
		request.Headers[HttpRequestHeader.UserAgent] = UserAgent_Chrome_Win10_Latest;
		if (AcceptLanguage != null)
		{
			request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage;
		}
		if (Accept != null)
		{
			request.Headers[HttpRequestHeader.Accept] = Accept;
		}
		if (Referer != null && isTranslationRequest)
		{
			request.Headers[HttpRequestHeader.Referer] = Referer;
		}
		if (AcceptCharset != null)
		{
			request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset;
		}
	}

	private void InspectResponse(XUnityWebResponse response)
	{
		CookieCollection newCookies = response.NewCookies;
		foreach (Cookie item in newCookies)
		{
			item.Domain = ".googleapis.com";
		}
		_cookieContainer.Add(newCookies);
	}

	public async Task SetupTKK()
	{
		_cookieContainer = new CookieContainer();
		XUnityWebResponse val3;
		try
		{
			XUnityWebClient val = new XUnityWebClient();
			XUnityWebRequest val2 = CreateWebSiteRequest();
			val3 = await val.SendAsync(val2);
		}
		catch (Exception)
		{
			return;
		}
		if (val3.Error != null || val3.Data == null)
		{
			return;
		}
		InspectResponse(val3);
		try
		{
			string data = val3.Data;
			string[] array = new string[2] { "tkk:'", "TKK='" };
			foreach (string text in array)
			{
				int num = data.IndexOf(text);
				if (num > -1)
				{
					int num2 = num + text.Length;
					int num3 = data.IndexOf("'", num2);
					string[] array2 = data.Substring(num2, num3 - num2).Split(new char[1] { '.' });
					if (array2.Length == 2)
					{
						m = long.Parse(array2[0]);
						s = long.Parse(array2[1]);
						break;
					}
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private long Vi(long r, string o)
	{
		for (int i = 0; i < o.Length; i += 3)
		{
			long num = o[i + 2];
			num = ((num >= 97) ? (num - 87) : (num - 48));
			num = (('+' == o[i + 1]) ? (r >> (int)num) : (r << (int)num));
			r = (('+' == o[i]) ? ((r + num) & 0xFFFFFFFFu) : (r ^ num));
		}
		return r;
	}

	private string Tk(string r)
	{
		List<long> list = new List<long>();
		for (int i = 0; i < r.Length; i++)
		{
			long num = r[i];
			if (128 > num)
			{
				list.Add(num);
				continue;
			}
			if (2048 > num)
			{
				list.Add((num >> 6) | 0xC0);
			}
			else if (55296 == (0xFC00 & num) && i + 1 < r.Length && 56320 == (0xFC00 & r[i + 1]))
			{
				num = 65536 + ((0x3FF & num) << 10) + (0x3FF & r[++i]);
				list.Add((num >> 18) | 0xF0);
				list.Add(((num >> 12) & 0x3F) | 0x80);
			}
			else
			{
				list.Add((num >> 12) | 0xE0);
				list.Add(((num >> 6) & 0x3F) | 0x80);
			}
			list.Add((0x3F & num) | 0x80);
		}
		long num2 = m;
		for (int j = 0; j < list.Count; j++)
		{
			num2 += list[j];
			num2 = Vi(num2, "+-a^+6");
		}
		num2 = Vi(num2, "+-3^+b+-f");
		num2 ^= s;
		if (0 > num2)
		{
			num2 = (0x7FFFFFFF & num2) + 2147483648u;
		}
		num2 %= 1000000;
		return num2.ToString(CultureInfo.InvariantCulture) + "." + (num2 ^ m).ToString(CultureInfo.InvariantCulture);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Http.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using Common.ExtProtocol;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Http.ExtProtocol")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Http.ExtProtocol")]
[assembly: AssemblyTitle("Http.ExtProtocol")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Http.ExtProtocol;

public abstract class ExtHttpEndpoint : IExtTranslateEndpoint
{
	public virtual void Initialize(string config)
	{
	}

	public virtual Task OnBeforeTranslate(IHttpTranslationContext context)
	{
		return null;
	}

	public abstract void OnCreateRequest(IHttpRequestCreationContext context);

	public virtual void OnInspectResponse(IHttpResponseInspectionContext context)
	{
	}

	public abstract void OnExtractTranslation(IHttpTranslationExtractionContext context);

	public async Task Translate(ITranslationContext context)
	{
		HttpTranslationContext httpContext = new HttpTranslationContext(context);
		await OnBeforeTranslate(httpContext);
		OnCreateRequest(httpContext);
		if (httpContext.Request == null)
		{
			httpContext.Fail("No request object was provided by the translator.");
		}
		XUnityWebResponse xUnityWebResponse2 = (httpContext.Response = await new XUnityWebClient().SendAsync(httpContext.Request));
		OnInspectResponse(httpContext);
		if (xUnityWebResponse2.Error != null)
		{
			httpContext.Fail("Error occurred while retrieving translation.", xUnityWebResponse2.Error);
		}
		if (xUnityWebResponse2.Data == null)
		{
			httpContext.Fail("Error occurred while retrieving translation. Nothing was returned.");
		}
		OnExtractTranslation(httpContext);
	}
}
internal class HttpTranslationContext : IHttpTranslationContext, ITranslationContextBase, IHttpRequestCreationContext, IHttpResponseInspectionContext, IHttpTranslationExtractionContext
{
	private readonly ITranslationContext _context;

	public string UntranslatedText => ((ITranslationContextBase)_context).UntranslatedText;

	public string[] UntranslatedTexts => ((ITranslationContextBase)_context).UntranslatedTexts;

	public UntranslatedTextInfo UntranslatedTextInfo => ((ITranslationContextBase)_context).UntranslatedTextInfo;

	public UntranslatedTextInfo[] UntranslatedTextInfos => ((ITranslationContextBase)_context).UntranslatedTextInfos;

	public string SourceLanguage => ((ITranslationContextBase)_context).SourceLanguage;

	public string DestinationLanguage => ((ITranslationContextBase)_context).DestinationLanguage;

	public XUnityWebResponse Response { get; internal set; }

	public XUnityWebRequest Request { get; internal set; }

	public object UserState
	{
		get
		{
			return ((ITranslationContextBase)_context).UserState;
		}
		set
		{
			((ITranslationContextBase)_context).UserState = value;
		}
	}

	internal HttpTranslationContext(ITranslationContext context)
	{
		_context = context;
	}

	public void Fail(string reason, Exception exception)
	{
		((ITranslationContextBase)_context).Fail(reason, exception);
	}

	public void Fail(string reason)
	{
		((ITranslationContextBase)_context).Fail(reason);
	}

	void IHttpRequestCreationContext.Complete(XUnityWebRequest request)
	{
		Request = request;
	}

	void IHttpTranslationExtractionContext.Complete(string translatedText)
	{
		_context.Complete(translatedText);
	}

	void IHttpTranslationExtractionContext.Complete(string[] translatedTexts)
	{
		_context.Complete(translatedTexts);
	}
}
public interface IHttpRequestCreationContext : IHttpTranslationContext, ITranslationContextBase
{
	void Complete(XUnityWebRequest request);
}
public interface IHttpResponseInspectionContext : IHttpTranslationContext, ITranslationContextBase
{
	XUnityWebRequest Request { get; }

	XUnityWebResponse Response { get; }
}
public interface IHttpTranslationContext : ITranslationContextBase
{
}
public interface IHttpTranslationExtractionContext : IHttpResponseInspectionContext, IHttpTranslationContext, ITranslationContextBase
{
	void Complete(string translatedText);

	void Complete(string[] translatedTexts);
}
public static class UserAgents
{
	public static readonly string Chrome_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36";

	public static readonly string Chrome_Win7_Latest = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36";

	public static readonly string Firefox_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0";

	public static readonly string Edge_Win10_Latest = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763";
}
public class XUnityWebClient : WebClient
{
	private HttpStatusCode? _responseCode;

	private CookieCollection _responseCookies;

	private CookieContainer _requestCookies;

	private WebHeaderCollection _requestHeaders;

	public XUnityWebClient()
	{
		base.Encoding = System.Text.Encoding.UTF8;
	}

	protected override WebRequest GetWebRequest(Uri address)
	{
		WebRequest webRequest = base.GetWebRequest(address);
		SetRequestVariables(webRequest);
		return webRequest;
	}

	protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
	{
		WebResponse webResponse = base.GetWebResponse(request, result);
		SetResponseVariables(webResponse);
		return webResponse;
	}

	protected override WebResponse GetWebResponse(WebRequest request)
	{
		WebResponse webResponse = base.GetWebResponse(request);
		SetResponseVariables(webResponse);
		return webResponse;
	}

	private void SetRequestVariables(WebRequest r)
	{
		if (r is HttpWebRequest httpWebRequest)
		{
			if (_requestCookies != null)
			{
				httpWebRequest.CookieContainer = _requestCookies;
			}
			if (_requestHeaders != null)
			{
				base.Headers = _requestHeaders;
			}
			httpWebRequest.ReadWriteTimeout = 50000;
			httpWebRequest.Timeout = 55000;
		}
	}

	private void SetResponseVariables(WebResponse r)
	{
		if (r is HttpWebResponse httpWebResponse)
		{
			_responseCode = httpWebResponse.StatusCode;
			_responseCookies = httpWebResponse.Cookies;
		}
	}

	public async Task<XUnityWebResponse> SendAsync(XUnityWebRequest request)
	{
		XUnityWebResponse response = new XUnityWebResponse();
		_requestCookies = request.Cookies;
		_requestHeaders = request.Headers;
		if (request.Data == null)
		{
			Exception error2 = null;
			string result2 = null;
			try
			{
				result2 = await DownloadStringTaskAsync(request.Address);
			}
			catch (Exception ex)
			{
				error2 = ex;
			}
			response.SetCompleted(_responseCode.Value, result2, base.ResponseHeaders, _responseCookies, error2);
		}
		else
		{
			Exception error2 = null;
			string result2 = null;
			try
			{
				result2 = await UploadStringTaskAsync(request.Address, request.Method, request.Data);
			}
			catch (Exception ex2)
			{
				error2 = ex2;
			}
			response.SetCompleted(_responseCode.Value, result2, base.ResponseHeaders, _responseCookies, error2);
		}
		return response;
	}
}
public class XUnityWebRequest
{
	private WebHeaderCollection _headers;

	public string Method { get; private set; }

	public Uri Address { get; private set; }

	public string Data { get; private set; }

	public CookieContainer Cookies { get; set; }

	public WebHeaderCollection Headers
	{
		get
		{
			if (_headers == null)
			{
				_headers = new WebHeaderCollection();
			}
			return _headers;
		}
		set
		{
			_headers = value;
		}
	}

	public XUnityWebRequest(string method, string address, string data)
	{
		Method = method;
		Address = new Uri(address);
		Data = data;
	}

	public XUnityWebRequest(string method, string address)
	{
		Method = method;
		Address = new Uri(address);
		Data = string.Empty;
	}

	public XUnityWebRequest(string address)
	{
		Method = "GET";
		Address = new Uri(address);
	}
}
public class XUnityWebResponse
{
	public HttpStatusCode Code { get; private set; }

	public string Data { get; private set; }

	public WebHeaderCollection Headers { get; private set; }

	public CookieCollection NewCookies { get; private set; }

	public Exception Error { get; private set; }

	internal bool IsCompleted { get; private set; }

	internal void SetCompleted(HttpStatusCode code, string data, WebHeaderCollection headers, CookieCollection newCookies, Exception error)
	{
		IsCompleted = true;
		Code = code;
		Data = data;
		Headers = headers;
		NewCookies = newCookies;
		Error = error;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/Newtonsoft.Json.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.1.25517")]
[assembly: AssemblyInformationalVersion("13.0.1+ae9fe44e1323e91bcbd185ca1a14099fba7c021f")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = num & _mask;
			for (Entry entry = _entries[num3]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			_mask = num;
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (text.IndexOf('.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] array = buffer.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int)
				{
					return (int)value;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array2 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double)
				{
					return (double)value;
				}
				double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal)
				{
					return (decimal)value;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		private void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable();
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable())
			{
				jsonTextReader.PropertyNameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object? value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object? value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object? value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
		{
			TraceJsonReader traceJsonReader = new TraceJsonReader(reader);
			if (reader.TokenType != 0)
			{
				traceJsonReader.WriteCurrentToken();
			}
			return traceJsonReader;
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter? GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal const int DefaultMaxDepth = 64;

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo? _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string? _dateFormatString;

		internal bool _dateFormatStringSet;

		internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling.GetValueOrDefault();
			}
			set
			{
				_preserveReferencesHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
	

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/FullNET/XUnity.AutoTranslator.Plugin.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("gravydevsupreme")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Package that contains a simple inter-process protocol format used in XUnity.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.ExtProtocol")]
[assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.ExtProtocol")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace XUnity.AutoTranslator.Plugin.ExtProtocol;

public class ConfigurationMessage : ProtocolMessage
{
	public static readonly string Type = "4";

	public string Config { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		Config = reader.ReadToEnd();
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.Write(Config);
	}
}
public static class ExtProtocolConvert
{
	private static readonly Dictionary<string, Type> IdToType;

	private static readonly Dictionary<Type, string> TypeToId;

	static ExtProtocolConvert()
	{
		IdToType = new Dictionary<string, Type>();
		TypeToId = new Dictionary<Type, string>();
		Register(TranslationRequest.Type, typeof(TranslationRequest));
		Register(TranslationResponse.Type, typeof(TranslationResponse));
		Register(TranslationError.Type, typeof(TranslationError));
		Register(ConfigurationMessage.Type, typeof(ConfigurationMessage));
	}

	public static void Register(string id, Type type)
	{
		IdToType[id] = type;
		TypeToId[type] = id;
	}

	public static string Encode(ProtocolMessage message)
	{
		StringWriter stringWriter = new StringWriter();
		string value = TypeToId[message.GetType()];
		stringWriter.WriteLine(value);
		message.Encode(stringWriter);
		return Convert.ToBase64String(Encoding.UTF8.GetBytes(stringWriter.ToString()), Base64FormattingOptions.None);
	}

	public static ProtocolMessage Decode(string message)
	{
		StringReader stringReader = new StringReader(Encoding.UTF8.GetString(Convert.FromBase64String(message)));
		string key = stringReader.ReadLine();
		ProtocolMessage obj = (ProtocolMessage)Activator.CreateInstance(IdToType[key]);
		obj.Decode(stringReader);
		return obj;
	}
}
public abstract class ProtocolMessage
{
	public Guid Id { get; set; }

	internal abstract void Decode(TextReader reader);

	internal abstract void Encode(TextWriter writer);
}
public enum StatusCode
{
	OK = 0,
	Blocked = 1,
	Unknown = 1000
}
public class TranslationError : ProtocolMessage
{
	public static readonly string Type = "3";

	public string Reason { get; set; }

	public StatusCode FailureCode { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		FailureCode = (StatusCode)int.Parse(reader.ReadLine());
		Reason = reader.ReadToEnd();
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine((int)FailureCode);
		writer.Write(Reason);
	}
}
public class TranslationRequest : ProtocolMessage
{
	public static readonly string Type = "1";

	private string[] _untranslatedTexts;

	public string SourceLanguage { get; set; }

	public string DestinationLanguage { get; set; }

	public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((TransmittableUntranslatedTextInfo x) => x.UntranslatedText).ToArray());

	public TransmittableUntranslatedTextInfo[] UntranslatedTextInfos { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		SourceLanguage = reader.ReadLine();
		DestinationLanguage = reader.ReadLine();
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		TransmittableUntranslatedTextInfo[] array = new TransmittableUntranslatedTextInfo[num];
		for (int i = 0; i < num; i++)
		{
			TransmittableUntranslatedTextInfo transmittableUntranslatedTextInfo = new TransmittableUntranslatedTextInfo();
			transmittableUntranslatedTextInfo.Decode(reader);
			array[i] = transmittableUntranslatedTextInfo;
		}
		UntranslatedTextInfos = array;
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine(SourceLanguage);
		writer.WriteLine(DestinationLanguage);
		writer.WriteLine(UntranslatedTextInfos.Length.ToString(CultureInfo.InvariantCulture));
		TransmittableUntranslatedTextInfo[] untranslatedTextInfos = UntranslatedTextInfos;
		for (int i = 0; i < untranslatedTextInfos.Length; i++)
		{
			untranslatedTextInfos[i].Encode(writer);
		}
	}
}
public class TranslationResponse : ProtocolMessage
{
	public static readonly string Type = "2";

	public string[] TranslatedTexts { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array = new string[num];
		for (int i = 0; i < num; i++)
		{
			string s = reader.ReadLine();
			string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s));
			array[i] = @string;
		}
		TranslatedTexts = array;
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine(TranslatedTexts.Length.ToString(CultureInfo.InvariantCulture));
		string[] translatedTexts = TranslatedTexts;
		foreach (string s in translatedTexts)
		{
			string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None);
			writer.WriteLine(value);
		}
	}
}
public class TransmittableUntranslatedTextInfo
{
	public string[] ContextBefore { get; set; }

	public string UntranslatedText { get; set; }

	public string[] ContextAfter { get; set; }

	public TransmittableUntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter)
	{
		ContextBefore = contextBefore;
		UntranslatedText = untranslatedText;
		ContextAfter = contextAfter;
	}

	public TransmittableUntranslatedTextInfo()
	{
	}

	internal void Encode(TextWriter writer)
	{
		string[] contextBefore = ContextBefore;
		writer.WriteLine(((contextBefore != null) ? contextBefore.Length : 0).ToString(CultureInfo.InvariantCulture));
		if (ContextBefore != null)
		{
			string[] contextBefore2 = ContextBefore;
			foreach (string s in contextBefore2)
			{
				string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None);
				writer.WriteLine(value);
			}
		}
		string[] contextAfter = ContextAfter;
		writer.WriteLine(((contextAfter != null) ? contextAfter.Length : 0).ToString(CultureInfo.InvariantCulture));
		if (ContextAfter != null)
		{
			string[] contextBefore2 = ContextAfter;
			foreach (string s2 in contextBefore2)
			{
				string value2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(s2), Base64FormattingOptions.None);
				writer.WriteLine(value2);
			}
		}
		string value3 = Convert.ToBase64String(Encoding.UTF8.GetBytes(UntranslatedText), Base64FormattingOptions.None);
		writer.WriteLine(value3);
	}

	internal void Decode(TextReader reader)
	{
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array = new string[num];
		for (int i = 0; i < num; i++)
		{
			string s = reader.ReadLine();
			string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s));
			array[i] = @string;
		}
		ContextBefore = array;
		int num2 = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array2 = new string[num2];
		for (int j = 0; j < num2; j++)
		{
			string s2 = reader.ReadLine();
			string string2 = Encoding.UTF8.GetString(Convert.FromBase64String(s2));
			array2[j] = string2;
		}
		ContextAfter = array2;
		string s3 = reader.ReadLine();
		string string3 = Encoding.UTF8.GetString(Convert.FromBase64String(s3));
		UntranslatedText = string3;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core;
using XUnity.AutoTranslator.Plugin.Core.Constants;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Extensions;
using XUnity.AutoTranslator.Plugin.Core.Shims;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;
using XUnity.Common.Extensions;
using XUnity.Common.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("GoogleTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GoogleTranslate")]
[assembly: AssemblyTitle("GoogleTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GoogleTranslate;

public class GoogleTranslateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"auto", "romaji", "af", "sq", "am", "ar", "hy", "az", "eu", "be",
		"bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs",
		"da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka",
		"de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu",
		"is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km",
		"ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg",
		"ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny",
		"ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr",
		"st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw",
		"sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz",
		"vi", "cy", "xh", "yi", "yo", "zu"
	};

	private static readonly string DefaultApiBackend = "https://translate.googleapis.com";

	private static readonly string DefaultUserBackend = "https://translate.google.com";

	private static readonly string HttpsServicePointTranslateTemplateUrl = "/translate_a/single?client=webapp&sl={0}&tl={1}&dt=t&tk={2}&q={3}";

	private static readonly string HttpsServicePointRomanizeTemplateUrl = "/translate_a/single?client=webapp&sl={0}&tl=en&dt=rm&tk={1}&q={2}";

	private static readonly Random RandomNumbers = new Random();

	private static readonly string[] Accepts = new string[3] { null, "*/*", "application/json" };

	private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" };

	private static readonly string[] AcceptCharsets = new string[2]
	{
		null,
		Encoding.UTF8.WebName
	};

	private static readonly string Accept = Accepts[RandomNumbers.Next(Accepts.Length)];

	private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)];

	private static readonly string AcceptCharset = AcceptCharsets[RandomNumbers.Next(AcceptCharsets.Length)];

	private string _selectedApiBackend;

	private string _selectedUserBackend;

	private string _httpsServicePointTranslateTemplateUrl;

	private string _httpsServicePointRomanizeTemplateUrl;

	private CookieContainer _cookieContainer;

	private bool _hasSetup;

	private long m = 427761L;

	private long s = 1179739010L;

	private int _translationsPerRequest = 10;

	private int _translationCount;

	private int _resetAfter = RandomNumbers.Next(75, 125);

	public override string Id => "GoogleTranslate";

	public override string FriendlyName => "Google! Translate";

	public override int MaxTranslationsPerRequest => _translationsPerRequest;

	public GoogleTranslateEndpoint()
	{
		_cookieContainer = new CookieContainer();
	}

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		if (context.DestinationLanguage == "romaji")
		{
			_translationsPerRequest = 1;
		}
		_selectedApiBackend = DefaultApiBackend;
		_selectedUserBackend = DefaultUserBackend;
		string orCreateSetting = context.GetOrCreateSetting<string>("Google", "ServiceUrl");
		if (!StringExtensions.IsNullOrWhiteSpace(orCreateSetting))
		{
			_selectedApiBackend = orCreateSetting;
			_selectedUserBackend = orCreateSetting;
			_httpsServicePointTranslateTemplateUrl = _selectedApiBackend + HttpsServicePointTranslateTemplateUrl;
			_httpsServicePointRomanizeTemplateUrl = _selectedApiBackend + HttpsServicePointRomanizeTemplateUrl;
			XuaLogger.AutoTranslator.Info("The default backend for google translate was overwritten.");
		}
		else
		{
			_selectedApiBackend = DefaultApiBackend;
			_selectedUserBackend = DefaultUserBackend;
			_httpsServicePointTranslateTemplateUrl = _selectedApiBackend + HttpsServicePointTranslateTemplateUrl;
			_httpsServicePointRomanizeTemplateUrl = _selectedApiBackend + HttpsServicePointRomanizeTemplateUrl;
		}
		context.DisableCertificateChecksFor(new string[2]
		{
			new Uri(_selectedApiBackend).Host,
			new Uri(_selectedUserBackend).Host
		});
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context)
	{
		if (!_hasSetup || _translationCount % _resetAfter == 0)
		{
			_resetAfter = RandomNumbers.Next(75, 125);
			_translationCount = 1;
			_hasSetup = true;
			IEnumerator enumerator = SetupTKK();
			while (enumerator.MoveNext())
			{
				yield return enumerator.Current;
			}
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		_translationCount++;
		string text = string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts);
		XUnityWebRequest val = ((!(((ITranslationContextBase)context).DestinationLanguage == "romaji")) ? new XUnityWebRequest(string.Format(_httpsServicePointTranslateTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Tk(text), Uri.EscapeDataString(text))) : new XUnityWebRequest(string.Format(_httpsServicePointRomanizeTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), Tk(text), Uri.EscapeDataString(text))));
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: true);
		context.Complete(val);
	}

	public override void OnInspectResponse(IHttpResponseInspectionContext context)
	{
		InspectResponse(context.Response);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		bool flag = ((ITranslationContextBase)context).DestinationLanguage == "romaji";
		int num = (flag ? 3 : 0);
		string data = ((IHttpResponseInspectionContext)context).Response.Data;
		JSONNode val = JSON.Parse(data);
		StringBuilder stringBuilder = new StringBuilder(data.Length);
		val = ((JSONNode)val.AsArray)[0];
		if (val.IsNull && flag)
		{
			context.Complete(((ITranslationContextBase)context).UntranslatedText);
			return;
		}
		Enumerator enumerator = ((JSONNode)val.AsArray).GetEnumerator();
		while (((Enumerator)(ref enumerator)).MoveNext())
		{
			string text = ((object)((JSONNode)JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray)[num]).ToString();
			text = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder))
			{
				stringBuilder.Append('\n');
			}
			stringBuilder.Append(text);
		}
		string text2 = stringBuilder.ToString();
		if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1)
		{
			context.Complete(text2);
			return;
		}
		string[] array = text2.Split(new char[1] { '\n' });
		List<string> list = new List<string>();
		int num2 = 0;
		string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts;
		for (int i = 0; i < untranslatedTexts.Length; i++)
		{
			int num3 = untranslatedTexts[i].Split(new char[1] { '\n' }).Length;
			string text3 = string.Empty;
			for (int j = 0; j < num3; j++)
			{
				if (num2 >= array.Length)
				{
					((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
				}
				string text4 = array[num2++];
				text3 += text4;
				if (j != num3 - 1)
				{
					text3 += "\n";
				}
			}
			list.Add(text3);
		}
		if (num2 != array.Length)
		{
			((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
		}
		context.Complete(list.ToArray());
	}

	private XUnityWebRequest CreateWebSiteRequest()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(_selectedUserBackend);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: false);
		return val;
	}

	private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest)
	{
		request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent);
		if (AcceptLanguage != null)
		{
			request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage;
		}
		if (Accept != null)
		{
			request.Headers[HttpRequestHeader.Accept] = Accept;
		}
		if (isTranslationRequest)
		{
			request.Headers[HttpRequestHeader.Referer] = _selectedUserBackend + "/";
		}
		if (AcceptCharset != null)
		{
			request.Headers[HttpRequestHeader.AcceptCharset] = AcceptCharset;
		}
	}

	private void InspectResponse(XUnityWebResponse response)
	{
		CookieCollection newCookies = response.NewCookies;
		if (newCookies == null)
		{
			return;
		}
		foreach (Cookie item in newCookies)
		{
			item.Domain = ".googleapis.com";
		}
		_cookieContainer.Add(newCookies);
	}

	public IEnumerator SetupTKK()
	{
		_cookieContainer = new CookieContainer();
		XUnityWebResponse response;
		try
		{
			XUnityWebClient val = new XUnityWebClient();
			XUnityWebRequest val2 = CreateWebSiteRequest();
			response = val.Send(val2);
		}
		catch (Exception ex)
		{
			XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead.");
			yield break;
		}
		IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator();
		while (iterator.MoveNext())
		{
			yield return iterator.Current;
		}
		if (((CustomYieldInstructionShim)response).IsTimedOut)
		{
			XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead.");
			yield break;
		}
		if (response.Error != null)
		{
			XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead.");
			yield break;
		}
		if (response.Data == null)
		{
			XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead.");
			yield break;
		}
		InspectResponse(response);
		try
		{
			string data = response.Data;
			bool flag = false;
			string[] array = new string[2] { "tkk:'", "TKK='" };
			foreach (string text in array)
			{
				int num = data.IndexOf(text);
				if (num > -1)
				{
					int num2 = num + text.Length;
					int num3 = data.IndexOf("'", num2);
					string[] array2 = data.Substring(num2, num3 - num2).Split(new char[1] { '.' });
					if (array2.Length == 2)
					{
						m = long.Parse(array2[0]);
						s = long.Parse(array2[1]);
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				XuaLogger.AutoTranslator.Warn("An error occurred while setting up GoogleTranslate TKK. Could not locate TKK value. Using fallback TKK values instead.");
			}
		}
		catch (Exception ex2)
		{
			XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up GoogleTranslate TKK. Using fallback TKK values instead.");
		}
	}

	private long Vi(long r, string o)
	{
		for (int i = 0; i < o.Length; i += 3)
		{
			long num = o[i + 2];
			num = ((num >= 97) ? (num - 87) : (num - 48));
			num = (('+' == o[i + 1]) ? (r >> (int)num) : (r << (int)num));
			r = (('+' == o[i]) ? ((r + num) & 0xFFFFFFFFu) : (r ^ num));
		}
		return r;
	}

	private string Tk(string r)
	{
		List<long> list = new List<long>();
		for (int i = 0; i < r.Length; i++)
		{
			long num = r[i];
			if (128 > num)
			{
				list.Add(num);
				continue;
			}
			if (2048 > num)
			{
				list.Add((num >> 6) | 0xC0);
			}
			else if (55296 == (0xFC00 & num) && i + 1 < r.Length && 56320 == (0xFC00 & r[i + 1]))
			{
				num = 65536 + ((0x3FF & num) << 10) + (0x3FF & r[++i]);
				list.Add((num >> 18) | 0xF0);
				list.Add(((num >> 12) & 0x3F) | 0x80);
			}
			else
			{
				list.Add((num >> 12) | 0xE0);
				list.Add(((num >> 6) & 0x3F) | 0x80);
			}
			list.Add((0x3F & num) | 0x80);
		}
		long num2 = m;
		for (int j = 0; j < list.Count; j++)
		{
			num2 += list[j];
			num2 = Vi(num2, "+-a^+6");
		}
		num2 = Vi(num2, "+-3^+b+-f");
		num2 ^= s;
		if (0 > num2)
		{
			num2 = (0x7FFFFFFF & num2) + 2147483648u;
		}
		num2 %= 1000000;
		return num2.ToString(CultureInfo.InvariantCulture) + "." + (num2 ^ m).ToString(CultureInfo.InvariantCulture);
	}
}
public class GoogleTranslateEndpointV2 : HttpEndpoint
{
	private static readonly char[] WordSplitters = new char[3] { ' ', '\r', '\n' };

	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"auto", "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn",
		"bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da",
		"nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de",
		"el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is",
		"ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko",
		"ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms",
		"ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps",
		"fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st",
		"sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv",
		"tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi",
		"cy", "xh", "yi", "yo", "zu"
	};

	private static readonly string DefaultUserBackend = "https://translate.google.com";

	private static readonly string TranslationPostTemplate = "[[[\"{0}\",\"[[\\\"{1}\\\",\\\"{2}\\\",\\\"{3}\\\",true],[null]]\",null,\"generic\"]]]";

	private static readonly string HttpsServicePointTranslateTemplateUrl = "/_/TranslateWebserverUi/data/batchexecute";

	private static readonly Random RandomNumbers = new Random();

	private static readonly string[] AcceptLanguages = new string[4] { null, "en-US,en;q=0.9", "en-US", "en" };

	private static readonly string AcceptLanguage = AcceptLanguages[RandomNumbers.Next(AcceptLanguages.Length)];

	private string _selectedUserBackend;

	private string _httpsServicePointTranslateTemplateUrl;

	private CookieContainer _cookieContainer;

	private bool _hasSetup;

	private long _FSID = LongRandom(long.MinValue, long.MaxValue, RandomNumbers);

	private int _translationCount;

	private int _resetAfter = RandomNumbers.Next(75, 125);

	private string _translateRpcId;

	private string _version;

	private bool _useSimplestSuggestion;

	private long _reqId;

	public override string Id => "GoogleTranslateV2";

	public override string FriendlyName => "Google! Translate (v2)";

	public override int MaxTranslationsPerRequest => 10;

	public GoogleTranslateEndpointV2()
	{
		_cookieContainer = new CookieContainer();
	}

	private static long LongRandom(long min, long max, Random rand)
	{
		byte[] array = new byte[8];
		rand.NextBytes(array);
		return Math.Abs(BitConverter.ToInt64(array, 0) % (max - min)) + min;
	}

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0114: 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)
		string orCreateSetting = context.GetOrCreateSetting<string>("GoogleV2", "ServiceUrl");
		if (!StringExtensions.IsNullOrWhiteSpace(orCreateSetting))
		{
			_selectedUserBackend = orCreateSetting;
			_httpsServicePointTranslateTemplateUrl = _selectedUserBackend + HttpsServicePointTranslateTemplateUrl;
			XuaLogger.AutoTranslator.Info("The default backend for google translate was overwritten.");
		}
		else
		{
			_selectedUserBackend = DefaultUserBackend;
			_httpsServicePointTranslateTemplateUrl = _selectedUserBackend + HttpsServicePointTranslateTemplateUrl;
		}
		_translateRpcId = context.GetOrCreateSetting<string>("GoogleV2", "RPCID", "MkEWBc");
		_version = context.GetOrCreateSetting<string>("GoogleV2", "VERSION", "boq_translate-webserver_20210323.10_p0");
		_useSimplestSuggestion = context.GetOrCreateSetting<bool>("GoogleV2", "UseSimplest", false);
		context.DisableCertificateChecksFor(new string[2]
		{
			new Uri(_selectedUserBackend).Host,
			new Uri(_selectedUserBackend).Host
		});
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context)
	{
		if (!_hasSetup || _translationCount % _resetAfter == 0)
		{
			_resetAfter = RandomNumbers.Next(75, 125);
			_translationCount = 1;
			_reqId = RandomNumbers.Next(0, 100000);
			_hasSetup = true;
			IEnumerator enumerator = SetupFSID();
			while (enumerator.MoveNext())
			{
				yield return enumerator.Current;
			}
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Expected O, but got Unknown
		_translationCount++;
		string text = JsonHelper.Escape(JsonHelper.Escape(string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts)));
		string text2 = string.Join("&", "rpcids=" + _translateRpcId, "f.sid=" + _FSID.ToString(CultureInfo.InvariantCulture), "bl=" + Uri.EscapeDataString(_version), "hl=en-US", "soc-app=1", "soc-platform=1", "soc-device=1", "_reqid=" + _reqId.ToString(CultureInfo.InvariantCulture), "rt=c");
		string text3 = "f.req=" + Uri.EscapeDataString(string.Format(TranslationPostTemplate, _translateRpcId, text, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage))) + "&";
		string text4 = _httpsServicePointTranslateTemplateUrl + "?" + text2;
		XUnityWebRequest val = new XUnityWebRequest("POST", text4, text3);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: true);
		_reqId += 100000L;
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		string data = ((IHttpResponseInspectionContext)context).Response.Data;
		data = data.Substring(6);
		string text = data.Substring(0, data.IndexOf("\n"));
		int length = int.Parse(text, CultureInfo.InvariantCulture);
		data = data.Substring(text.Length, length);
		string text2 = ((object)((JSONNode)((JSONNode)JSON.Parse(data).AsArray)[0].AsArray)[2]).ToString();
		string text3 = JsonHelper.Unescape(text2.Substring(1, text2.Length - 2));
		JSONNode obj = ((JSONNode)((JSONNode)((JSONNode)((JSONNode)JSON.Parse(text3).AsArray)[1].AsArray)[0].AsArray)[0].AsArray)[5];
		StringBuilder stringBuilder = new StringBuilder(text3.Length);
		Enumerator enumerator = ((JSONNode)obj.AsArray).GetEnumerator();
		while (((Enumerator)(ref enumerator)).MoveNext())
		{
			JSONArray asArray = JSONNode.op_Implicit(((Enumerator)(ref enumerator)).Current).AsArray;
			string text4 = ((object)((JSONNode)asArray)[0]).ToString();
			text4 = JsonHelper.Unescape(text4.Substring(1, text4.Length - 2));
			if (StringExtensions.IsNullOrWhiteSpace(text4))
			{
				continue;
			}
			if (_useSimplestSuggestion && ((JSONNode)asArray).Count > 1)
			{
				JSONNode obj2 = ((JSONNode)asArray)[1];
				JSONArray val = ((obj2 != null) ? obj2.AsArray : null);
				if ((JSONNode)(object)val != (object)null)
				{
					HashSet<string> hashSet = new HashSet<string>();
					hashSet.Add(text4);
					for (int i = 0; i < ((JSONNode)val).Count; i++)
					{
						string text5 = ((object)((JSONNode)val)[i]).ToString();
						text5 = JsonHelper.Unescape(text5.Substring(1, text5.Length - 2));
						hashSet.Add(text5);
					}
					if (hashSet.Count > 1)
					{
						XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: Primary translation is '" + text4 + "', but found multiple suggestion:");
						foreach (string item in hashSet)
						{
							XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: " + item);
						}
						int wordsInPrimary = text4.Split(WordSplitters).Length;
						text4 = (from x in hashSet
							where x.Split(WordSplitters).Length < wordsInPrimary
							orderby x.Split(WordSplitters).Length
							select x).FirstOrDefault() ?? text4;
						XuaLogger.AutoTranslator.Debug("[GoogleTranslateV2]: Selecting translation: " + text4);
					}
				}
			}
			if (!StringBuilderExtensions.EndsWithWhitespaceOrNewline(stringBuilder))
			{
				stringBuilder.Append('\n');
			}
			stringBuilder.Append(text4);
		}
		string text6 = stringBuilder.ToString();
		if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1)
		{
			context.Complete(text6);
			return;
		}
		string[] array = text6.Split(new char[1] { '\n' });
		List<string> list = new List<string>();
		int num = 0;
		string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts;
		for (int j = 0; j < untranslatedTexts.Length; j++)
		{
			int num2 = untranslatedTexts[j].Split(new char[1] { '\n' }).Length;
			string text7 = string.Empty;
			for (int k = 0; k < num2; k++)
			{
				if (num >= array.Length)
				{
					((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
				}
				string text8 = array[num++];
				text7 += text8;
				if (k != num2 - 1)
				{
					text7 += "\n";
				}
			}
			list.Add(text7);
		}
		if (num != array.Length)
		{
			((ITranslationContextBase)context).Fail("Batch operation received incorrect number of translations.");
		}
		context.Complete(list.ToArray());
	}

	private XUnityWebRequest CreateWebSiteRequest()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(_selectedUserBackend);
		val.Cookies = _cookieContainer;
		AddHeaders(val, isTranslationRequest: false);
		return val;
	}

	private void AddHeaders(XUnityWebRequest request, bool isTranslationRequest)
	{
		request.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent);
		if (AcceptLanguage != null)
		{
			request.Headers[HttpRequestHeader.AcceptLanguage] = AcceptLanguage;
		}
		if (isTranslationRequest)
		{
			request.Headers[HttpRequestHeader.Referer] = _selectedUserBackend + "/";
			request.Headers["X-Same-Domain"] = "1";
			request.Headers["DNT"] = "1";
			request.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded;charset=UTF-8";
			request.Headers[HttpRequestHeader.Accept] = "*/*";
			request.Headers["Origin"] = _selectedUserBackend;
		}
		else
		{
			request.Headers["Upgrade-Insecure-Requests"] = "1";
		}
	}

	public IEnumerator SetupFSID()
	{
		_cookieContainer = new CookieContainer();
		XUnityWebResponse response;
		try
		{
			XUnityWebClient val = new XUnityWebClient();
			XUnityWebRequest val2 = CreateWebSiteRequest();
			response = val.Send(val2);
		}
		catch (Exception ex)
		{
			XuaLogger.AutoTranslator.Warn(ex, "An error occurred while setting up GoogleTranslate FSID. Using random instead.");
			yield break;
		}
		IEnumerator iterator = ((CustomYieldInstructionShim)response).GetSupportedEnumerator();
		while (iterator.MoveNext())
		{
			yield return iterator.Current;
		}
		if (((CustomYieldInstructionShim)response).IsTimedOut)
		{
			XuaLogger.AutoTranslator.Warn("A timeout error occurred while setting up GoogleTranslate FSID. Using random instead.");
			yield break;
		}
		if (response.Error != null)
		{
			XuaLogger.AutoTranslator.Warn(response.Error, "An error occurred while setting up GoogleTranslate FSID. Using random instead.");
			yield break;
		}
		if (response.Data == null)
		{
			XuaLogger.AutoTranslator.Warn((Exception)null, "An error occurred while setting up GoogleTranslate FSID. Using random instead.");
			yield break;
		}
		try
		{
			string data = response.Data;
			bool flag = false;
			string[] array = new string[1] { "FdrFJe\":\"" };
			foreach (string text in array)
			{
				int num = data.IndexOf(text);
				if (num > -1)
				{
					int num2 = num + text.Length;
					int num3 = data.IndexOf("\"", num2);
					string s = data.Substring(num2, num3 - num2);
					_FSID = long.Parse(s, CultureInfo.InvariantCulture);
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				XuaLogger.AutoTranslator.Warn("An error occurred while setting up GoogleTranslate FSID. Could not locate FSID value. Using random instead.");
			}
		}
		catch (Exception ex2)
		{
			XuaLogger.AutoTranslator.Warn(ex2, "An error occurred while setting up GoogleTranslate FSID. Using random instead.");
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslateCompat.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("GoogleTranslateCompat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GoogleTranslateCompat")]
[assembly: AssemblyTitle("GoogleTranslateCompat")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GoogleTranslateCompat;

internal class GoogleTranslateCompatEndpoint : ExtProtocolEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"auto", "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn",
		"bs", "bg", "ca", "ceb", "zh-CN", "zh-TW", "co", "hr", "cs", "da",
		"nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de",
		"el", "gu", "ht", "ha", "haw", "he", "hi", "hmn", "hu", "is",
		"ig", "id", "ga", "it", "ja", "jw", "kn", "kk", "km", "ko",
		"ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms",
		"ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "ps",
		"fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st",
		"sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv",
		"tl", "tg", "ta", "te", "th", "tr", "uk", "ur", "uz", "vi",
		"cy", "xh", "yi", "yo", "zu"
	};

	public override string Id => "GoogleTranslateCompat";

	public override string FriendlyName => "Google! Translate (Compat)";

	public override int MaxConcurrency => 1;

	public override int MaxTranslationsPerRequest => 10;

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		((ExtProtocolEndpoint)this).Initialize(context);
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
		((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes("GoogleTranslateCompat.ExtProtocol.GoogleTranslateCompatTranslate, GoogleTranslateCompat.ExtProtocol"));
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/GoogleTranslateLegitimate.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("GoogleTranslateLegitimate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GoogleTranslateLegitimate")]
[assembly: AssemblyTitle("GoogleTranslateLegitimate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GoogleTranslateLegitimate;

internal class GoogleTranslateLegitimateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs",
		"bg", "ca", "ceb", "zh", "zh-Hans", "zh-Hant", "zh-CN", "zh-TW", "co", "hr",
		"cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl",
		"ka", "de", "el", "gu", "ht", "ha", "haw", "he", "hi", "hmn",
		"hu", "is", "ig", "id", "ga", "it", "ja", "jw", "kn", "kk",
		"km", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk",
		"mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no",
		"ny", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd",
		"sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su",
		"sw", "sv", "tl", "tg", "ta", "te", "th", "tr", "uk", "ur",
		"uz", "vi", "cy", "xh", "yi", "yo", "zu"
	};

	private static readonly string HttpsServiceUrl = "https://translation.googleapis.com/language/translate/v2";

	private string _key;

	public override string Id => "GoogleTranslateLegitimate";

	public override string FriendlyName => "Google! Translate (Authenticated)";

	public override int MaxTranslationsPerRequest => 10;

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		_key = context.GetOrCreateSetting<string>("GoogleLegitimate", "GoogleAPIKey", "");
		if (string.IsNullOrEmpty(_key))
		{
			throw new EndpointInitializationException("The GoogleTranslateLegitimate endpoint requires an API key which has not been provided.");
		}
		context.DisableCertificateChecksFor(new string[1] { "translation.googleapis.com" });
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		StringBuilder stringBuilder = new StringBuilder(HttpsServiceUrl);
		stringBuilder.Append("?key=").Append(Uri.EscapeDataString(_key));
		stringBuilder.Append("&source=").Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage));
		stringBuilder.Append("&target=").Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage));
		for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++)
		{
			string stringToEscape = ((ITranslationContextBase)context).UntranslatedTexts[i];
			stringBuilder.Append("&q=").Append(Uri.EscapeDataString(stringToEscape));
		}
		XUnityWebRequest val = new XUnityWebRequest("POST", stringBuilder.ToString());
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		JSONArray asArray = ((JSONNode)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["data"].AsObject)["translations"].AsArray;
		List<string> list = new List<string>();
		for (int i = 0; i < ((JSONNode)asArray).Count; i++)
		{
			string text = ((object)((JSONNode)((JSONNode)asArray)[i].AsObject)["translatedText"]).ToString();
			string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			list.Add(item);
		}
		context.Complete(list.ToArray());
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/LecPowerTranslator15.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Win32;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.ExtProtocol;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("LecPowerTranslator15")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LecPowerTranslator15")]
[assembly: AssemblyTitle("LecPowerTranslator15")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LecPowerTranslator15;

internal class LecPowerTranslator15Endpoint : ExtProtocolEndpoint
{
	public override string Id => "LecPowerTranslator15";

	public override string FriendlyName => "LEC Power Translator 15";

	public override int MaxConcurrency => 1;

	public override int MaxTranslationsPerRequest => 50;

	public override void Initialize(IInitializationContext context)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		string defaultInstallationPath = GetDefaultInstallationPath();
		string text = context.GetOrCreateSetting<string>("LecPowerTranslator15", "InstallationPath", defaultInstallationPath);
		if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(defaultInstallationPath))
		{
			context.SetSetting<string>("LecPowerTranslator15", "InstallationPath", defaultInstallationPath);
			text = defaultInstallationPath;
		}
		if (string.IsNullOrEmpty(text))
		{
			throw new EndpointInitializationException("The LecPowerTranslator15 requires the path to the installation folder.");
		}
		context.DisableSpamChecks();
		string text2 = Path.Combine(context.TranslatorDirectory, Path.Combine("FullNET", "Lec.ExtProtocol.exe"));
		if (!File.Exists(text2))
		{
			throw new EndpointInitializationException("Could not find any executable at '" + text2 + "'");
		}
		((ExtProtocolEndpoint)this).ExecutablePath = text2;
		((ExtProtocolEndpoint)this).Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes(text));
		if (context.SourceLanguage != "ja")
		{
			throw new EndpointInitializationException("Current implementation only supports japanese-to-english.");
		}
		if (context.DestinationLanguage != "en")
		{
			throw new EndpointInitializationException("Current implementation only supports japanese-to-english.");
		}
	}

	public static string GetDefaultInstallationPath()
	{
		try
		{
			string text = GetInstallationPathFromRegistry();
			if (!string.IsNullOrEmpty(text))
			{
				text = new DirectoryInfo(text).Parent.FullName;
			}
			return text ?? string.Empty;
		}
		catch
		{
			return string.Empty;
		}
	}

	public static string GetInstallationPathFromRegistry()
	{
		try
		{
			if (IntPtr.Size == 8)
			{
				return (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LogoMedia\\LEC Power Translator 15\\Configuration", "ApplicationPath", null);
			}
			return (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\LogoMedia\\LEC Power Translator 15\\Configuration", "ApplicationPath", null);
		}
		catch
		{
			return null;
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/LingoCloudTranslate.dll

Decompiled 10 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("LingoCloudTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LingoCloudTranslate")]
[assembly: AssemblyTitle("LingoCloudTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LingoCloudTranslate;

internal class LingoCloudTranslateEndpoint : HttpEndpoint
{
	private static readonly Dictionary<string, string> SupportedLanguages = new Dictionary<string, string>
	{
		{ "en", "en" },
		{ "ja", "ja" },
		{ "jp", "ja" },
		{ "zh", "zh" },
		{ "zh-Hans", "zh" },
		{ "zh-CN", "zh" },
		{ "zh-Hant", "zh" },
		{ "zh-TW", "zh" }
	};

	private static readonly string HttpServicePointTemplateUrl = "https://api.interpreter.caiyunai.com/v1/translator";

	public string _token;

	public override string Id => "LingoCloudTranslate";

	public override string FriendlyName => "CaiYun Translator";

	private string FixLanguage(string lang)
	{
		if (SupportedLanguages.TryGetValue(lang, out var value))
		{
			return value;
		}
		return lang;
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		_token = context.GetOrCreateSetting<string>("LingoCloud", "LingoCloudToken", "");
		if (string.IsNullOrEmpty(_token))
		{
			throw new EndpointInitializationException("The LingoCloudTranslate endpoint requires an App Id which has not been provided.");
		}
		context.DisableCertificateChecksFor(new string[1] { "api.interpreter.caiyunai.com" });
		if (!SupportedLanguages.ContainsKey(context.SourceLanguage))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.ContainsKey(context.DestinationLanguage))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		JSONObject val = new JSONObject();
		string[] untranslatedTexts = ((ITranslationContextBase)context).UntranslatedTexts;
		foreach (string text in untranslatedTexts)
		{
			((JSONNode)val)["source"].Add(JSONNode.op_Implicit(text));
		}
		((JSONNode)val)["trans_type"] = JSONNode.op_Implicit("auto2" + FixLanguage(((ITranslationContextBase)context).DestinationLanguage));
		((JSONNode)val)["request_id"] = JSONNode.op_Implicit("demo");
		((JSONNode)val)["detect"] = JSONNode.op_Implicit("true");
		string text2 = ((object)val).ToString();
		XUnityWebRequest val2 = new XUnityWebRequest("POST", HttpServicePointTemplateUrl, text2);
		val2.Headers[HttpRequestHeader.ContentType] = "application/json";
		val2.Headers["X-Authorization"] = "token " + _token;
		context.Complete(val2);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		string text = ((object)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["target"]).ToString();
		string text2 = JsonHelper.Unescape(text.Substring(2, text.Length - 4));
		context.Complete(text2);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/PapagoTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core;
using XUnity.AutoTranslator.Plugin.Core.Constants;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Shims;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;
using XUnity.Common.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("PapagoTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PapagoTranslate")]
[assembly: AssemblyTitle("PapagoTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PapagoTranslate;

public class PapagoTranslateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"en", "ko", "zh-CN", "zh-TW", "es", "fr", "ru", "vi", "th", "id",
		"de", "ja", "hi", "pt"
	};

	private static readonly HashSet<string> SMTLanguages = new HashSet<string> { "hi", "pt" };

	private static readonly string UrlBase = "https://papago.naver.com";

	private static readonly string UrlN2MT = "/apis/n2mt/translate";

	private static readonly string UrlNSMT = "/apis/nsmt/translate";

	private static readonly string FormUrlEncodedTemplate = "deviceId={0}&locale=en&dict=false&honorific=false&instant=true&source={1}&target={2}&text={3}";

	private static readonly Random RandomNumbers = new Random();

	private static readonly Guid UUID = Guid.NewGuid();

	private static readonly Regex PatternSource = new Regex("/vendors~main[^\"]+", RegexOptions.Singleline);

	private static readonly Regex PatternVersion = new Regex("v\\d\\.\\d\\.\\d_[^\"]+", RegexOptions.Singleline);

	private string _version;

	private bool _isSMT;

	private int _translationCount;

	private int _resetAfter;

	public override string Id => "PapagoTranslate";

	public override string FriendlyName => "Papago Translator";

	public override int MaxTranslationsPerRequest => 10;

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-Hans":
		case "zh":
			return "zh-CN";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		context.DisableCertificateChecksFor(new string[1] { "papago.naver.com" });
		string text = FixLanguage(context.SourceLanguage);
		string text2 = FixLanguage(context.DestinationLanguage);
		_isSMT = SMTLanguages.Contains(text) || SMTLanguages.Contains(text2);
		if (!SupportedLanguages.Contains(text2))
		{
			throw new EndpointInitializationException("The language '" + context.DestinationLanguage + "' is not supported by Papago Translate.");
		}
		if (_isSMT && text != "en" && text2 != "en")
		{
			throw new EndpointInitializationException("Translation from '" + context.SourceLanguage + "' to '" + context.DestinationLanguage + "' is not supported by Papago Translate.");
		}
	}

	public override IEnumerator OnBeforeTranslate(IHttpTranslationContext context)
	{
		if (_resetAfter == 0 || _translationCount % _resetAfter == 0)
		{
			_translationCount = 1;
			_resetAfter = RandomNumbers.Next(150, 200);
			IEnumerator enumerator = SetupVersion();
			while (enumerator.MoveNext())
			{
				yield return enumerator.Current;
			}
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		string text = Uri.EscapeDataString(string.Join("\n", ((ITranslationContextBase)context).UntranslatedTexts));
		XUnityWebRequest val = new XUnityWebRequest("POST", UrlBase + (_isSMT ? UrlNSMT : UrlN2MT), string.Format(FormUrlEncodedTemplate, UUID, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), text));
		DateTime utcNow = DateTime.UtcNow;
		DateTime minValue = DateTime.MinValue;
		double num = Math.Truncate(utcNow.Subtract(minValue.AddYears(1969)).TotalMilliseconds);
		byte[] bytes = Encoding.UTF8.GetBytes(_version);
		byte[] bytes2 = Encoding.UTF8.GetBytes($"{UUID}\n{val.Address}\n{num}");
		string arg = Convert.ToBase64String(new HMACMD5(bytes).ComputeHash(bytes2));
		val.Headers[HttpRequestHeader.UserAgent] = (string.IsNullOrEmpty(AutoTranslatorSettings.UserAgent) ? UserAgents.Chrome_Win10_Latest : AutoTranslatorSettings.UserAgent);
		val.Headers["Authorization"] = $"PPG {UUID}:{arg}";
		val.Headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
		val.Headers["Timestamp"] = num.ToString();
		context.Complete(val);
		_translationCount++;
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		string text = ((object)((JSONNode)JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data).AsObject)["translatedText"]).ToString();
		string text2 = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
		if (((ITranslationContextBase)context).UntranslatedTexts.Length == 1)
		{
			context.Complete(text2);
			return;
		}
		string[] array = text2.Split(new char[1] { '\n' });
		string[] array2 = new string[((ITranslationContextBase)context).UntranslatedTexts.Length];
		int num = 0;
		for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++)
		{
			string[] array3 = ((ITranslationContextBase)context).UntranslatedTexts[i].Split(new char[1] { '\n' });
			StringBuilder stringBuilder = new StringBuilder();
			for (int j = 0; j < array3.Length; j++)
			{
				string value = array[num++];
				if (array3.Length - 1 == j)
				{
					stringBuilder.Append(value);
				}
				else
				{
					stringBuilder.AppendLine(value);
				}
			}
			array2[i] = stringBuilder.ToString();
		}
		if (num != array.Length)
		{
			((ITranslationContextBase)context).Fail("Received invalid number of translations in batch.");
		}
		context.Complete(array2);
	}

	private IEnumerator SetupVersion()
	{
		XUnityWebClient client = new XUnityWebClient();
		XUnityWebResponse response2 = client.Send(new XUnityWebRequest(UrlBase));
		IEnumerator iterator2 = ((CustomYieldInstructionShim)response2).GetSupportedEnumerator();
		while (iterator2.MoveNext())
		{
			yield return iterator2.Current;
		}
		Match match = PatternSource.Match(response2.Data);
		if (!match.Success)
		{
			XuaLogger.AutoTranslator.Warn("Could not parse papago page");
			yield break;
		}
		string value = match.Value;
		response2 = client.Send(new XUnityWebRequest(UrlBase + value));
		iterator2 = ((CustomYieldInstructionShim)response2).GetSupportedEnumerator();
		while (iterator2.MoveNext())
		{
			yield return iterator2.Current;
		}
		Match match2 = PatternVersion.Match(response2.Data);
		if (!match2.Success)
		{
			XuaLogger.AutoTranslator.Warn("Could not parse papago version");
			yield break;
		}
		XuaLogger.AutoTranslator.Debug("Current papago version is " + match2.Value);
		_version = match2.Value;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/WatsonTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Www;
using XUnity.AutoTranslator.Plugin.Core.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("WatsonTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WatsonTranslate")]
[assembly: AssemblyTitle("WatsonTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace WatsonTranslate;

internal class WatsonTranslateEndpoint : WwwEndpoint
{
	private static readonly HashSet<string> SupportedLanguagePairs = new HashSet<string>
	{
		"ar-en", "ca-es", "zh-en", "zh-TW-en", "cs-en", "da-en", "nl-en", "en-ar", "en-cs", "en-da",
		"en-de", "en-es", "en-fi", "en-fr", "en-hi", "en-it", "en-ja", "en-ko", "en-nb", "en-nl",
		"en-pl", "en-pt", "en-ru", "en-sv", "en-tr", "en-zh", "en-zh-TW", "fi-en", "fr-de", "fr-en",
		"fr-es", "de-en", "de-fr", "de-it", "hi-en", "hu-en", "it-de", "it-en", "ja-en", "ko-en",
		"nb-en", "pl-en", "pt-en", "ru-en", "es-ca", "es-en", "es-fr", "sv-en", "tr-en"
	};

	private string _fullUrl;

	private string _url;

	private string _key;

	public override string Id => "WatsonTranslate";

	public override string FriendlyName => "Watson Language Translator";

	public override int MaxTranslationsPerRequest => 10;

	private string FixLanguage(string lang)
	{
		switch (lang)
		{
		case "zh-CN":
		case "zh-Hans":
			return "zh";
		case "zh-Hant":
			return "zh-TW";
		default:
			return lang;
		}
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		_url = context.GetOrCreateSetting<string>("Watson", "Url", "");
		_key = context.GetOrCreateSetting<string>("Watson", "Key", "");
		if (string.IsNullOrEmpty(_url))
		{
			throw new EndpointInitializationException("The WatsonTranslate endpoint requires a url which has not been provided.");
		}
		if (string.IsNullOrEmpty(_key))
		{
			throw new EndpointInitializationException("The WatsonTranslate endpoint requires a key which has not been provided.");
		}
		_fullUrl = _url.TrimEnd(new char[1] { '/' }) + "/v3/translate?version=2018-05-01";
		string text = FixLanguage(context.SourceLanguage) + "-" + FixLanguage(context.DestinationLanguage);
		if (!SupportedLanguagePairs.Contains(text))
		{
			throw new EndpointInitializationException("The language model '" + text + "' is not supported.");
		}
	}

	public override void OnCreateRequest(IWwwRequestCreationContext context)
	{
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("{\"text\":[");
		for (int i = 0; i < ((ITranslationContextBase)context).UntranslatedTexts.Length; i++)
		{
			string value = JsonHelper.Escape(((ITranslationContextBase)context).UntranslatedTexts[i]);
			stringBuilder.Append("\"").Append(value).Append("\"");
			if (((ITranslationContextBase)context).UntranslatedTexts.Length - 1 != i)
			{
				stringBuilder.Append(",");
			}
		}
		stringBuilder.Append("],\"model_id\":\"").Append(FixLanguage(((ITranslationContextBase)context).SourceLanguage)).Append("-")
			.Append(FixLanguage(((ITranslationContextBase)context).DestinationLanguage))
			.Append("\"}");
		WwwRequestInfo val = new WwwRequestInfo(_fullUrl, stringBuilder.ToString());
		val.Headers["Accept"] = "application/json";
		val.Headers["Content-Type"] = "application/json";
		val.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("apikey:" + _key));
		context.Complete(val);
	}

	public override void OnExtractTranslation(IWwwTranslationExtractionContext context)
	{
		JSONArray asArray = ((JSONNode)JSON.Parse(context.ResponseData).AsObject)["translations"].AsArray;
		List<string> list = new List<string>();
		for (int i = 0; i < ((JSONNode)asArray).Count; i++)
		{
			string text = ((object)((JSONNode)((JSONNode)asArray)[i].AsObject)["translation"]).ToString();
			string item = JsonHelper.Unescape(text.Substring(1, text.Length - 2));
			list.Add(item);
		}
		context.Complete(list.ToArray());
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/Translators/YandexTranslate.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using SimpleJSON;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Endpoints.Http;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("YandexTranslate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("YandexTranslate")]
[assembly: AssemblyTitle("YandexTranslate")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace YandexTranslate;

internal class YandexTranslateEndpoint : HttpEndpoint
{
	private static readonly HashSet<string> SupportedLanguages = new HashSet<string>
	{
		"az", "sq", "am", "en", "ar", "hy", "af", "eu", "ba", "be",
		"bn", "my", "bg", "bs", "cy", "hu", "vi", "ht", "gl", "nl",
		"mrj", "el", "ka", "gu", "da", "he", "yi", "id", "ga", "it",
		"is", "es", "kk", "kn", "ca", "ky", "zh", "ko", "xh", "km",
		"lo", "la", "lv", "lt", "lb", "mg", "ms", "ml", "mt", "mk",
		"mi", "mr", "mhr", "mn", "de", "ne", "no", "pa", "pap", "fa",
		"pl", "pt", "ro", "ru", "ceb", "sr", "si", "sk", "sl", "sw",
		"su", "tg", "th", "tl", "ta", "tt", "te", "tr", "udm", "uz",
		"uk", "ur", "fi", "fr", "hi", "hr", "cs", "sv", "gd", "et",
		"eo", "jv", "ja"
	};

	private static readonly string HttpsServicePointTemplateUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key={3}&text={2}&lang={0}-{1}&format=plain";

	private string _key;

	public override string Id => "YandexTranslate";

	public override string FriendlyName => "Yandex Translate";

	private string FixLanguage(string lang)
	{
		if (lang == "zh-CN" || lang == "zh-Hans")
		{
			return "zh";
		}
		return lang;
	}

	public override void Initialize(IInitializationContext context)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		_key = context.GetOrCreateSetting<string>("Yandex", "YandexAPIKey", "");
		context.DisableCertificateChecksFor(new string[1] { "translate.yandex.net" });
		if (string.IsNullOrEmpty(_key))
		{
			throw new EndpointInitializationException("The YandexTranslate endpoint requires an API key which has not been provided.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.SourceLanguage)))
		{
			throw new EndpointInitializationException("The source language '" + context.SourceLanguage + "' is not supported.");
		}
		if (!SupportedLanguages.Contains(FixLanguage(context.DestinationLanguage)))
		{
			throw new EndpointInitializationException("The destination language '" + context.DestinationLanguage + "' is not supported.");
		}
	}

	public override void OnCreateRequest(IHttpRequestCreationContext context)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		XUnityWebRequest val = new XUnityWebRequest(string.Format(HttpsServicePointTemplateUrl, FixLanguage(((ITranslationContextBase)context).SourceLanguage), FixLanguage(((ITranslationContextBase)context).DestinationLanguage), Uri.EscapeDataString(((ITranslationContextBase)context).UntranslatedText), _key));
		val.Headers[HttpRequestHeader.Accept] = "*/*";
		val.Headers[HttpRequestHeader.AcceptCharset] = "UTF-8";
		context.Complete(val);
	}

	public override void OnExtractTranslation(IHttpTranslationExtractionContext context)
	{
		JSONNode obj = JSON.Parse(((IHttpResponseInspectionContext)context).Response.Data);
		string text = ((object)((JSONNode)obj.AsObject)["code"]).ToString();
		if (text != "200")
		{
			((ITranslationContextBase)context).Fail("Received bad response code: " + text);
		}
		string text2 = ((object)((JSONNode)obj.AsObject)["text"]).ToString();
		string text3 = JsonHelper.Unescape(text2.Substring(2, text2.Length - 4));
		if (string.IsNullOrEmpty(text3))
		{
			((ITranslationContextBase)context).Fail("Received no translation.");
		}
		context.Complete(text3);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.BepInEx.dll

Decompiled 10 months ago
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using ExIni;
using XUnity.AutoTranslator.Plugin.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("XUnity.AutoTranslator.Plugin.BepInEx")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("5.3.0.0")]
[assembly: AssemblyInformationalVersion("5.3.0")]
[assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.BepInEx")]
[assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.BepInEx")]
[assembly: AssemblyVersion("5.3.0.0")]
namespace XUnity.AutoTranslator.Plugin.BepInEx;

[BepInPlugin("gravydevsupreme.xunity.autotranslator", "XUnity Auto Translator", "5.3.0")]
public class AutoTranslatorPlugin : BaseUnityPlugin, IPluginEnvironment
{
	private IniFile _file;

	private string _configPath;

	public IniFile Preferences => _file ?? (_file = ReloadConfig());

	public string ConfigPath { get; }

	public string TranslationPath { get; }

	public bool AllowDefaultInitializeHarmonyDetourBridge => false;

	public AutoTranslatorPlugin()
	{
		ConfigPath = Paths.ConfigPath;
		TranslationPath = Paths.BepInExRootPath;
		_configPath = Path.Combine(ConfigPath, "AutoTranslatorConfig.ini");
	}

	public IniFile ReloadConfig()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (!File.Exists(_configPath))
		{
			return (IniFile)(((object)_file) ?? ((object)new IniFile()));
		}
		IniFile val = IniFile.FromFile(_configPath);
		if (_file == null)
		{
			return _file = val;
		}
		_file.Merge(val);
		return _file;
	}

	public void SaveConfig()
	{
		_file.Save(_configPath);
	}

	private void Awake()
	{
		PluginLoader.LoadWithConfig((IPluginEnvironment)(object)this);
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.Core.dll

Decompiled 10 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Cache;
using System.Net.Security;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using DynamicLinq;
using ExIni;
using Harmony;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Encryption;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using UnityEngine;
using UnityEngine.SceneManagement;
using XUnity.AutoTranslator.Plugin.Core.AssetRedirection;
using XUnity.AutoTranslator.Plugin.Core.Configuration;
using XUnity.AutoTranslator.Plugin.Core.Debugging;
using XUnity.AutoTranslator.Plugin.Core.Endpoints;
using XUnity.AutoTranslator.Plugin.Core.Extensions;
using XUnity.AutoTranslator.Plugin.Core.Fonts;
using XUnity.AutoTranslator.Plugin.Core.Hooks;
using XUnity.AutoTranslator.Plugin.Core.Hooks.NGUI;
using XUnity.AutoTranslator.Plugin.Core.Hooks.TextMeshPro;
using XUnity.AutoTranslator.Plugin.Core.Hooks.UGUI;
using XUnity.AutoTranslator.Plugin.Core.Managed.Textures;
using XUnity.AutoTranslator.Plugin.Core.Parsing;
using XUnity.AutoTranslator.Plugin.Core.Properties;
using XUnity.AutoTranslator.Plugin.Core.Shims;
using XUnity.AutoTranslator.Plugin.Core.Text;
using XUnity.AutoTranslator.Plugin.Core.Textures;
using XUnity.AutoTranslator.Plugin.Core.UI;
using XUnity.AutoTranslator.Plugin.Core.UIResize;
using XUnity.AutoTranslator.Plugin.Core.Utilities;
using XUnity.AutoTranslator.Plugin.Core.Web;
using XUnity.AutoTranslator.Plugin.Core.Web.Internal;
using XUnity.AutoTranslator.Plugin.ExtProtocol;
using XUnity.AutoTranslator.Plugin.Utilities;
using XUnity.Common.Constants;
using XUnity.Common.Extensions;
using XUnity.Common.Harmony;
using XUnity.Common.Logging;
using XUnity.Common.MonoMod;
using XUnity.Common.Utilities;
using XUnity.ResourceRedirector;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.Core")]
[assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.Core")]
[assembly: AssemblyInformationalVersion("5.3.0")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyDescription("Main development dependency for XUnity Auto Translator.")]
[assembly: AssemblyFileVersion("5.3.0.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("gravydevsupreme")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: InternalsVisibleTo("XUnity.AutoTranslator.Plugin.Core.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("5.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 DynamicLinq
{
	internal static class DynamicQueryable
	{
		public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)
		{
			return (IQueryable<T>)((IQueryable)source).Where(predicate, values);
		}

		public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			LambdaExpression expression = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
			return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Where", new Type[1] { source.ElementType }, source.Expression, Expression.Quote(expression)));
		}

		public static IQueryable Select(this IQueryable source, string selector, params object[] values)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			LambdaExpression lambdaExpression = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
			return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Select", new Type[2]
			{
				source.ElementType,
				lambdaExpression.Body.Type
			}, source.Expression, Expression.Quote(lambdaExpression)));
		}

		public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values)
		{
			return (IQueryable<T>)((IQueryable)source).OrderBy(ordering, values);
		}

		public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (ordering == null)
			{
				throw new ArgumentNullException("ordering");
			}
			ParameterExpression[] parameters = new ParameterExpression[1] { Expression.Parameter(source.ElementType, "") };
			IEnumerable<DynamicOrdering> enumerable = new ExpressionParser(parameters, ordering, values).ParseOrdering();
			Expression expression = source.Expression;
			string text = "OrderBy";
			string text2 = "OrderByDescending";
			foreach (DynamicOrdering item in enumerable)
			{
				expression = Expression.Call(typeof(Queryable), item.Ascending ? text : text2, new Type[2]
				{
					source.ElementType,
					item.Selector.Type
				}, expression, Expression.Quote(Expression.Lambda(item.Selector, parameters)));
				text = "ThenBy";
				text2 = "ThenByDescending";
			}
			return source.Provider.CreateQuery(expression);
		}

		public static IQueryable Take(this IQueryable source, int count)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Take", new Type[1] { source.ElementType }, source.Expression, Expression.Constant(count)));
		}

		public static IQueryable Skip(this IQueryable source, int count)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Skip", new Type[1] { source.ElementType }, source.Expression, Expression.Constant(count)));
		}

		public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (keySelector == null)
			{
				throw new ArgumentNullException("keySelector");
			}
			if (elementSelector == null)
			{
				throw new ArgumentNullException("elementSelector");
			}
			LambdaExpression lambdaExpression = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values);
			LambdaExpression lambdaExpression2 = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values);
			return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "GroupBy", new Type[3]
			{
				source.ElementType,
				lambdaExpression.Body.Type,
				lambdaExpression2.Body.Type
			}, source.Expression, Expression.Quote(lambdaExpression), Expression.Quote(lambdaExpression2)));
		}

		public static bool Any(this IQueryable source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return (bool)source.Provider.Execute(Expression.Call(typeof(Queryable), "Any", new Type[1] { source.ElementType }, source.Expression));
		}

		public static int Count(this IQueryable source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return (int)source.Provider.Execute(Expression.Call(typeof(Queryable), "Count", new Type[1] { source.ElementType }, source.Expression));
		}
	}
	internal abstract class DynamicClass
	{
		public override string ToString()
		{
			PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{");
			for (int i = 0; i < properties.Length; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append(properties[i].Name);
				stringBuilder.Append("=");
				stringBuilder.Append(properties[i].GetValue(this, null));
			}
			stringBuilder.Append("}");
			return stringBuilder.ToString();
		}
	}
	internal class DynamicProperty
	{
		private string name;

		private Type type;

		public string Name => name;

		public Type Type => type;

		public DynamicProperty(string name, Type type)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			this.name = name;
			this.type = type;
		}
	}
	internal static class DynamicExpression
	{
		public static Expression Parse(Type resultType, string expression, params object[] values)
		{
			return new ExpressionParser(null, expression, values).Parse(resultType);
		}

		public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values)
		{
			return ParseLambda(new ParameterExpression[1] { Expression.Parameter(itType, "") }, resultType, expression, values);
		}

		public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values)
		{
			return Expression.Lambda(new ExpressionParser(parameters, expression, values).Parse(resultType), parameters);
		}

		public static Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values)
		{
			return (Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values);
		}

		public static Type CreateClass(params DynamicProperty[] properties)
		{
			throw new NotImplementedException();
		}

		public static Type CreateClass(IEnumerable<DynamicProperty> properties)
		{
			throw new NotImplementedException();
		}
	}
	internal class DynamicOrdering
	{
		public Expression Selector;

		public bool Ascending;
	}
	internal class Signature : IEquatable<Signature>
	{
		public DynamicProperty[] properties;

		public int hashCode;

		public Signature(IEnumerable<DynamicProperty> properties)
		{
			this.properties = properties.ToArray();
			hashCode = 0;
			foreach (DynamicProperty property in properties)
			{
				hashCode ^= property.Name.GetHashCode() ^ property.Type.GetHashCode();
			}
		}

		public override int GetHashCode()
		{
			return hashCode;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is Signature))
			{
				return false;
			}
			return Equals((Signature)obj);
		}

		public bool Equals(Signature other)
		{
			if (properties.Length != other.properties.Length)
			{
				return false;
			}
			for (int i = 0; i < properties.Length; i++)
			{
				if (properties[i].Name != other.properties[i].Name || (object)properties[i].Type != other.properties[i].Type)
				{
					return false;
				}
			}
			return true;
		}
	}
	internal sealed class ParseException : Exception
	{
		private int position;

		public int Position => position;

		public ParseException(string message, int position)
			: base(message)
		{
			this.position = position;
		}

		public override string ToString()
		{
			return $"{Message} (at index {position})";
		}
	}
	internal class ExpressionParser
	{
		private struct Token
		{
			public TokenId id;

			public string text;

			public int pos;
		}

		private enum TokenId
		{
			Unknown,
			End,
			Identifier,
			StringLiteral,
			IntegerLiteral,
			RealLiteral,
			Exclamation,
			Percent,
			Amphersand,
			OpenParen,
			CloseParen,
			Asterisk,
			Plus,
			Comma,
			Minus,
			Dot,
			Slash,
			Colon,
			LessThan,
			Equal,
			GreaterThan,
			Question,
			OpenBracket,
			CloseBracket,
			Bar,
			ExclamationEqual,
			DoubleAmphersand,
			LessThanEqual,
			LessGreater,
			DoubleEqual,
			GreaterThanEqual,
			DoubleBar
		}

		private interface ILogicalSignatures
		{
			void F(bool x, bool y);

			void F(bool? x, bool? y);
		}

		private interface IArithmeticSignatures
		{
			void F(int x, int y);

			void F(uint x, uint y);

			void F(long x, long y);

			void F(ulong x, ulong y);

			void F(float x, float y);

			void F(double x, double y);

			void F(decimal x, decimal y);

			void F(int? x, int? y);

			void F(uint? x, uint? y);

			void F(long? x, long? y);

			void F(ulong? x, ulong? y);

			void F(float? x, float? y);

			void F(double? x, double? y);

			void F(decimal? x, decimal? y);
		}

		private interface IRelationalSignatures : IArithmeticSignatures
		{
			void F(string x, string y);

			void F(char x, char y);

			void F(DateTime x, DateTime y);

			void F(TimeSpan x, TimeSpan y);

			void F(char? x, char? y);

			void F(DateTime? x, DateTime? y);

			void F(TimeSpan? x, TimeSpan? y);
		}

		private interface IEqualitySignatures : IRelationalSignatures, IArithmeticSignatures
		{
			void F(bool x, bool y);

			void F(bool? x, bool? y);
		}

		private interface IAddSignatures : IArithmeticSignatures
		{
			void F(DateTime x, TimeSpan y);

			void F(TimeSpan x, TimeSpan y);

			void F(DateTime? x, TimeSpan? y);

			void F(TimeSpan? x, TimeSpan? y);
		}

		private interface ISubtractSignatures : IAddSignatures, IArithmeticSignatures
		{
			void F(DateTime x, DateTime y);

			void F(DateTime? x, DateTime? y);
		}

		private interface INegationSignatures
		{
			void F(int x);

			void F(long x);

			void F(float x);

			void F(double x);

			void F(decimal x);

			void F(int? x);

			void F(long? x);

			void F(float? x);

			void F(double? x);

			void F(decimal? x);
		}

		private interface INotSignatures
		{
			void F(bool x);

			void F(bool? x);
		}

		private interface IEnumerableSignatures
		{
			void Where(bool predicate);

			void Any();

			void Any(bool predicate);

			void All(bool predicate);

			void Count();

			void Count(bool predicate);

			void Min(object selector);

			void Max(object selector);

			void Sum(int selector);

			void Sum(int? selector);

			void Sum(long selector);

			void Sum(long? selector);

			void Sum(float selector);

			void Sum(float? selector);

			void Sum(double selector);

			void Sum(double? selector);

			void Sum(decimal selector);

			void Sum(decimal? selector);

			void Average(int selector);

			void Average(int? selector);

			void Average(long selector);

			void Average(long? selector);

			void Average(float selector);

			void Average(float? selector);

			void Average(double selector);

			void Average(double? selector);

			void Average(decimal selector);

			void Average(decimal? selector);
		}

		private class MethodData
		{
			public MethodBase MethodBase;

			public ParameterInfo[] Parameters;

			public Expression[] Args;
		}

		private static readonly Type[] predefinedTypes = new Type[20]
		{
			typeof(object),
			typeof(bool),
			typeof(char),
			typeof(string),
			typeof(sbyte),
			typeof(byte),
			typeof(short),
			typeof(ushort),
			typeof(int),
			typeof(uint),
			typeof(long),
			typeof(ulong),
			typeof(float),
			typeof(double),
			typeof(decimal),
			typeof(DateTime),
			typeof(TimeSpan),
			typeof(Guid),
			typeof(Math),
			typeof(Convert)
		};

		private static readonly Expression trueLiteral = Expression.Constant(true);

		private static readonly Expression falseLiteral = Expression.Constant(false);

		private static readonly Expression nullLiteral = Expression.Constant(null);

		private static readonly string keywordIt = "it";

		private static readonly string keywordIif = "iif";

		private static readonly string keywordNew = "new";

		private static Dictionary<string, object> keywords;

		private Dictionary<string, object> symbols;

		private IDictionary<string, object> externals;

		private Dictionary<Expression, string> literals;

		private ParameterExpression it;

		private string text;

		private int textPos;

		private int textLen;

		private char ch;

		private Token token;

		public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values)
		{
			if (expression == null)
			{
				throw new ArgumentNullException("expression");
			}
			if (keywords == null)
			{
				keywords = CreateKeywords();
			}
			symbols = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
			literals = new Dictionary<Expression, string>();
			if (parameters != null)
			{
				ProcessParameters(parameters);
			}
			if (values != null)
			{
				ProcessValues(values);
			}
			text = expression;
			textLen = text.Length;
			SetTextPos(0);
			NextToken();
		}

		private void ProcessParameters(ParameterExpression[] parameters)
		{
			foreach (ParameterExpression parameterExpression in parameters)
			{
				if (!string.IsNullOrEmpty(parameterExpression.Name))
				{
					AddSymbol(parameterExpression.Name, parameterExpression);
				}
			}
			if (parameters.Length == 1 && string.IsNullOrEmpty(parameters[0].Name))
			{
				it = parameters[0];
			}
		}

		private void ProcessValues(object[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				object obj = values[i];
				if (i == values.Length - 1 && obj is IDictionary<string, object>)
				{
					externals = (IDictionary<string, object>)obj;
				}
				else
				{
					AddSymbol("@" + i.ToString(CultureInfo.InvariantCulture), obj);
				}
			}
		}

		private void AddSymbol(string name, object value)
		{
			if (symbols.ContainsKey(name))
			{
				throw ParseError("The identifier '{0}' was defined more than once", name);
			}
			symbols.Add(name, value);
		}

		public Expression Parse(Type resultType)
		{
			int pos = token.pos;
			Expression expression = ParseExpression();
			if ((object)resultType != null && (expression = PromoteExpression(expression, resultType, exact: true)) == null)
			{
				throw ParseError(pos, "Expression of type '{0}' expected", GetTypeName(resultType));
			}
			ValidateToken(TokenId.End, "Syntax error");
			return expression;
		}

		public IEnumerable<DynamicOrdering> ParseOrdering()
		{
			List<DynamicOrdering> list = new List<DynamicOrdering>();
			while (true)
			{
				Expression selector = ParseExpression();
				bool ascending = true;
				if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending"))
				{
					NextToken();
				}
				else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending"))
				{
					NextToken();
					ascending = false;
				}
				list.Add(new DynamicOrdering
				{
					Selector = selector,
					Ascending = ascending
				});
				if (token.id != TokenId.Comma)
				{
					break;
				}
				NextToken();
			}
			ValidateToken(TokenId.End, "Syntax error");
			return list;
		}

		private Expression ParseExpression()
		{
			int pos = token.pos;
			Expression expression = ParseLogicalOr();
			if (token.id == TokenId.Question)
			{
				NextToken();
				Expression expr = ParseExpression();
				ValidateToken(TokenId.Colon, "':' expected");
				NextToken();
				Expression expr2 = ParseExpression();
				expression = GenerateConditional(expression, expr, expr2, pos);
			}
			return expression;
		}

		private Expression ParseLogicalOr()
		{
			Expression left = ParseLogicalAnd();
			while (this.token.id == TokenId.DoubleBar || TokenIdentifierIs("or"))
			{
				Token token = this.token;
				NextToken();
				Expression right = ParseLogicalAnd();
				CheckAndPromoteOperands(typeof(ILogicalSignatures), token.text, ref left, ref right, token.pos);
				left = Expression.OrElse(left, right);
			}
			return left;
		}

		private Expression ParseLogicalAnd()
		{
			Expression left = ParseComparison();
			while (this.token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and"))
			{
				Token token = this.token;
				NextToken();
				Expression right = ParseComparison();
				CheckAndPromoteOperands(typeof(ILogicalSignatures), token.text, ref left, ref right, token.pos);
				left = Expression.AndAlso(left, right);
			}
			return left;
		}

		private Expression ParseComparison()
		{
			Expression left = ParseAdditive();
			while (this.token.id == TokenId.Equal || this.token.id == TokenId.DoubleEqual || this.token.id == TokenId.ExclamationEqual || this.token.id == TokenId.LessGreater || this.token.id == TokenId.GreaterThan || this.token.id == TokenId.GreaterThanEqual || this.token.id == TokenId.LessThan || this.token.id == TokenId.LessThanEqual)
			{
				Token token = this.token;
				NextToken();
				Expression right = ParseAdditive();
				bool flag = token.id == TokenId.Equal || token.id == TokenId.DoubleEqual || token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater;
				if (flag && !left.Type.IsValueType && !right.Type.IsValueType)
				{
					if ((object)left.Type != right.Type)
					{
						if (left.Type.IsAssignableFrom(right.Type))
						{
							right = Expression.Convert(right, left.Type);
						}
						else
						{
							if (!right.Type.IsAssignableFrom(left.Type))
							{
								throw IncompatibleOperandsError(token.text, left, right, token.pos);
							}
							left = Expression.Convert(left, right.Type);
						}
					}
				}
				else if (IsEnumType(left.Type) || IsEnumType(right.Type))
				{
					if ((object)left.Type != right.Type)
					{
						Expression expression;
						if ((expression = PromoteExpression(right, left.Type, exact: true)) != null)
						{
							right = expression;
						}
						else
						{
							if ((expression = PromoteExpression(left, right.Type, exact: true)) == null)
							{
								throw IncompatibleOperandsError(token.text, left, right, token.pos);
							}
							left = expression;
						}
					}
				}
				else
				{
					CheckAndPromoteOperands(flag ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures), token.text, ref left, ref right, token.pos);
				}
				switch (token.id)
				{
				case TokenId.Equal:
				case TokenId.DoubleEqual:
					left = GenerateEqual(left, right);
					break;
				case TokenId.ExclamationEqual:
				case TokenId.LessGreater:
					left = GenerateNotEqual(left, right);
					break;
				case TokenId.GreaterThan:
					left = GenerateGreaterThan(left, right);
					break;
				case TokenId.GreaterThanEqual:
					left = GenerateGreaterThanEqual(left, right);
					break;
				case TokenId.LessThan:
					left = GenerateLessThan(left, right);
					break;
				case TokenId.LessThanEqual:
					left = GenerateLessThanEqual(left, right);
					break;
				}
			}
			return left;
		}

		private Expression ParseAdditive()
		{
			Expression left = ParseMultiplicative();
			while (this.token.id == TokenId.Plus || this.token.id == TokenId.Minus || this.token.id == TokenId.Amphersand)
			{
				Token token = this.token;
				NextToken();
				Expression right = ParseMultiplicative();
				TokenId id = token.id;
				if (id != TokenId.Amphersand)
				{
					if (id != TokenId.Plus)
					{
						if (id == TokenId.Minus)
						{
							CheckAndPromoteOperands(typeof(ISubtractSignatures), token.text, ref left, ref right, token.pos);
							left = GenerateSubtract(left, right);
						}
						continue;
					}
					if ((object)left.Type != typeof(string) && (object)right.Type != typeof(string))
					{
						CheckAndPromoteOperands(typeof(IAddSignatures), token.text, ref left, ref right, token.pos);
						left = GenerateAdd(left, right);
						continue;
					}
				}
				left = GenerateStringConcat(left, right);
			}
			return left;
		}

		private Expression ParseMultiplicative()
		{
			Expression left = ParseUnary();
			while (this.token.id == TokenId.Asterisk || this.token.id == TokenId.Slash || this.token.id == TokenId.Percent || TokenIdentifierIs("mod"))
			{
				Token token = this.token;
				NextToken();
				Expression right = ParseUnary();
				CheckAndPromoteOperands(typeof(IArithmeticSignatures), token.text, ref left, ref right, token.pos);
				switch (token.id)
				{
				case TokenId.Asterisk:
					left = Expression.Multiply(left, right);
					break;
				case TokenId.Slash:
					left = Expression.Divide(left, right);
					break;
				case TokenId.Identifier:
				case TokenId.Percent:
					left = Expression.Modulo(left, right);
					break;
				}
			}
			return left;
		}

		private Expression ParseUnary()
		{
			if (this.token.id == TokenId.Minus || this.token.id == TokenId.Exclamation || TokenIdentifierIs("not"))
			{
				Token token = this.token;
				NextToken();
				if (token.id == TokenId.Minus && (this.token.id == TokenId.IntegerLiteral || this.token.id == TokenId.RealLiteral))
				{
					this.token.text = "-" + this.token.text;
					this.token.pos = token.pos;
					return ParsePrimary();
				}
				Expression expr = ParseUnary();
				if (token.id == TokenId.Minus)
				{
					CheckAndPromoteOperand(typeof(INegationSignatures), token.text, ref expr, token.pos);
					return Expression.Negate(expr);
				}
				CheckAndPromoteOperand(typeof(INotSignatures), token.text, ref expr, token.pos);
				return Expression.Not(expr);
			}
			return ParsePrimary();
		}

		private Expression ParsePrimary()
		{
			Expression expression = ParsePrimaryStart();
			while (true)
			{
				if (token.id == TokenId.Dot)
				{
					NextToken();
					expression = ParseMemberAccess(null, expression);
					continue;
				}
				if (token.id != TokenId.OpenBracket)
				{
					break;
				}
				expression = ParseElementAccess(expression);
			}
			return expression;
		}

		private Expression ParsePrimaryStart()
		{
			return token.id switch
			{
				TokenId.Identifier => ParseIdentifier(), 
				TokenId.StringLiteral => ParseStringLiteral(), 
				TokenId.IntegerLiteral => ParseIntegerLiteral(), 
				TokenId.RealLiteral => ParseRealLiteral(), 
				TokenId.OpenParen => ParseParenExpression(), 
				_ => throw ParseError("Expression expected"), 
			};
		}

		private Expression ParseStringLiteral()
		{
			ValidateToken(TokenId.StringLiteral);
			char c = token.text[0];
			string text = token.text.Substring(1, token.text.Length - 2);
			int startIndex = 0;
			while (true)
			{
				int num = text.IndexOf(c, startIndex);
				if (num < 0)
				{
					break;
				}
				text = text.Remove(num, 1);
				startIndex = num + 1;
			}
			if (c == '\'')
			{
				if (text.Length != 1)
				{
					throw ParseError("Character literal must contain exactly one character");
				}
				NextToken();
				return CreateLiteral(text[0], text);
			}
			NextToken();
			return CreateLiteral(text, text);
		}

		private Expression ParseIntegerLiteral()
		{
			ValidateToken(TokenId.IntegerLiteral);
			string text = token.text;
			if (text[0] != '-')
			{
				if (!ulong.TryParse(text, out var result))
				{
					throw ParseError("Invalid integer literal '{0}'", text);
				}
				NextToken();
				if (result <= int.MaxValue)
				{
					return CreateLiteral((int)result, text);
				}
				if (result <= uint.MaxValue)
				{
					return CreateLiteral((uint)result, text);
				}
				if (result <= long.MaxValue)
				{
					return CreateLiteral((long)result, text);
				}
				return CreateLiteral(result, text);
			}
			if (!long.TryParse(text, out var result2))
			{
				throw ParseError("Invalid integer literal '{0}'", text);
			}
			NextToken();
			if (result2 >= int.MinValue && result2 <= int.MaxValue)
			{
				return CreateLiteral((int)result2, text);
			}
			return CreateLiteral(result2, text);
		}

		private Expression ParseRealLiteral()
		{
			ValidateToken(TokenId.RealLiteral);
			string text = token.text;
			object obj = null;
			char c = text[text.Length - 1];
			double result2;
			if (c == 'F' || c == 'f')
			{
				if (float.TryParse(text.Substring(0, text.Length - 1), out var result))
				{
					obj = result;
				}
			}
			else if (double.TryParse(text, out result2))
			{
				obj = result2;
			}
			if (obj == null)
			{
				throw ParseError("Invalid real literal '{0}'", text);
			}
			NextToken();
			return CreateLiteral(obj, text);
		}

		private Expression CreateLiteral(object value, string text)
		{
			ConstantExpression constantExpression = Expression.Constant(value);
			literals.Add(constantExpression, text);
			return constantExpression;
		}

		private Expression ParseParenExpression()
		{
			ValidateToken(TokenId.OpenParen, "'(' expected");
			NextToken();
			Expression result = ParseExpression();
			ValidateToken(TokenId.CloseParen, "')' or operator expected");
			NextToken();
			return result;
		}

		private Expression ParseIdentifier()
		{
			ValidateToken(TokenId.Identifier);
			if (keywords.TryGetValue(token.text, out var value))
			{
				if (value is Type)
				{
					return ParseTypeAccess((Type)value);
				}
				if (value == keywordIt)
				{
					return ParseIt();
				}
				if (value == keywordIif)
				{
					return ParseIif();
				}
				if (value == keywordNew)
				{
					return ParseNew();
				}
				NextToken();
				return (Expression)value;
			}
			if (symbols.TryGetValue(token.text, out value) || (externals != null && externals.TryGetValue(token.text, out value)))
			{
				Expression expression = value as Expression;
				if (expression == null)
				{
					expression = Expression.Constant(value);
				}
				else if (expression is LambdaExpression lambda)
				{
					return ParseLambdaInvocation(lambda);
				}
				NextToken();
				return expression;
			}
			if (it != null)
			{
				return ParseMemberAccess(null, it);
			}
			throw ParseError("Unknown identifier '{0}'", token.text);
		}

		private Expression ParseIt()
		{
			if (it == null)
			{
				throw ParseError("No 'it' is in scope");
			}
			NextToken();
			return it;
		}

		private Expression ParseIif()
		{
			int pos = token.pos;
			NextToken();
			Expression[] array = ParseArgumentList();
			if (array.Length != 3)
			{
				throw ParseError(pos, "The 'iif' function requires three arguments");
			}
			return GenerateConditional(array[0], array[1], array[2], pos);
		}

		private Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int errorPos)
		{
			if ((object)test.Type != typeof(bool))
			{
				throw ParseError(errorPos, "The first expression must be of type 'Boolean'");
			}
			if ((object)expr1.Type != expr2.Type)
			{
				Expression expression = ((expr2 != nullLiteral) ? PromoteExpression(expr1, expr2.Type, exact: true) : null);
				Expression expression2 = ((expr1 != nullLiteral) ? PromoteExpression(expr2, expr1.Type, exact: true) : null);
				if (expression != null && expression2 == null)
				{
					expr1 = expression;
				}
				else
				{
					if (expression2 == null || expression != null)
					{
						string text = ((expr1 != nullLiteral) ? expr1.Type.Name : "null");
						string text2 = ((expr2 != nullLiteral) ? expr2.Type.Name : "null");
						if (expression != null && expression2 != null)
						{
							throw ParseError(errorPos, "Both of the types '{0}' and '{1}' convert to the other", text, text2);
						}
						throw ParseError(errorPos, "Neither of the types '{0}' and '{1}' converts to the other", text, text2);
					}
					expr2 = expression2;
				}
			}
			return Expression.Condition(test, expr1, expr2);
		}

		private Expression ParseNew()
		{
			NextToken();
			ValidateToken(TokenId.OpenParen, "'(' expected");
			NextToken();
			List<DynamicProperty> list = new List<DynamicProperty>();
			List<Expression> list2 = new List<Expression>();
			while (true)
			{
				int pos = token.pos;
				Expression expression = ParseExpression();
				string name;
				if (TokenIdentifierIs("as"))
				{
					NextToken();
					name = GetIdentifier();
					NextToken();
				}
				else
				{
					if (!(expression is MemberExpression memberExpression))
					{
						throw ParseError(pos, "Expression is missing an 'as' clause");
					}
					name = memberExpression.Member.Name;
				}
				list2.Add(expression);
				list.Add(new DynamicProperty(name, expression.Type));
				if (token.id != TokenId.Comma)
				{
					break;
				}
				NextToken();
			}
			ValidateToken(TokenId.CloseParen, "')' or ',' expected");
			NextToken();
			Type type = DynamicExpression.CreateClass(list);
			MemberBinding[] array = new MemberBinding[list.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Expression.Bind(type.GetProperty(list[i].Name), list2[i]);
			}
			return Expression.MemberInit(Expression.New(type), array);
		}

		private Expression ParseLambdaInvocation(LambdaExpression lambda)
		{
			int pos = token.pos;
			NextToken();
			Expression[] array = ParseArgumentList();
			if (FindMethod(lambda.Type, "Invoke", staticAccess: false, array, out var _) != 1)
			{
				throw ParseError(pos, "Argument list incompatible with lambda expression");
			}
			return Expression.Invoke(lambda, array);
		}

		private Expression ParseTypeAccess(Type type)
		{
			int pos = token.pos;
			NextToken();
			if (token.id == TokenId.Question)
			{
				if (!type.IsValueType || IsNullableType(type))
				{
					throw ParseError(pos, "Type '{0}' has no nullable form", GetTypeName(type));
				}
				type = typeof(Nullable<>).MakeGenericType(type);
				NextToken();
			}
			if (token.id == TokenId.OpenParen)
			{
				Expression[] array = ParseArgumentList();
				MethodBase method;
				switch (FindBestMethod(type.GetConstructors(), array, out method))
				{
				case 0:
					if (array.Length == 1)
					{
						return GenerateConversion(array[0], type, pos);
					}
					throw ParseError(pos, "No matching constructor in type '{0}'", GetTypeName(type));
				case 1:
					return Expression.New((ConstructorInfo)method, array);
				default:
					throw ParseError(pos, "Ambiguous invocation of '{0}' constructor", GetTypeName(type));
				}
			}
			ValidateToken(TokenId.Dot, "'.' or '(' expected");
			NextToken();
			return ParseMemberAccess(type, null);
		}

		private Expression GenerateConversion(Expression expr, Type type, int errorPos)
		{
			Type type2 = expr.Type;
			if ((object)type2 == type)
			{
				return expr;
			}
			if (type2.IsValueType && type.IsValueType)
			{
				if ((IsNullableType(type2) || IsNullableType(type)) && (object)GetNonNullableType(type2) == GetNonNullableType(type))
				{
					return Expression.Convert(expr, type);
				}
				if (((IsNumericType(type2) || IsEnumType(type2)) && IsNumericType(type)) || IsEnumType(type))
				{
					return Expression.ConvertChecked(expr, type);
				}
			}
			if (type2.IsAssignableFrom(type) || type.IsAssignableFrom(type2) || type2.IsInterface || type.IsInterface)
			{
				return Expression.Convert(expr, type);
			}
			throw ParseError(errorPos, "A value of type '{0}' cannot be converted to type '{1}'", GetTypeName(type2), GetTypeName(type));
		}

		private Expression ParseMemberAccess(Type type, Expression instance)
		{
			if (instance != null)
			{
				type = instance.Type;
			}
			int pos = token.pos;
			string identifier = GetIdentifier();
			NextToken();
			if (token.id == TokenId.OpenParen)
			{
				if (instance != null && (object)type != typeof(string))
				{
					Type type2 = FindGenericType(typeof(IEnumerable<>), type);
					if ((object)type2 != null)
					{
						Type elementType = type2.GetGenericArguments()[0];
						return ParseAggregate(instance, elementType, identifier, pos);
					}
				}
				Expression[] array = ParseArgumentList();
				MethodBase method;
				switch (FindMethod(type, identifier, instance == null, array, out method))
				{
				case 0:
					throw ParseError(pos, "No applicable method '{0}' exists in type '{1}'", identifier, GetTypeName(type));
				case 1:
				{
					MethodInfo methodInfo = (MethodInfo)method;
					if (!IsPredefinedType(methodInfo.DeclaringType))
					{
						throw ParseError(pos, "Methods on type '{0}' are not accessible", GetTypeName(methodInfo.DeclaringType));
					}
					if ((object)methodInfo.ReturnType == typeof(void))
					{
						throw ParseError(pos, "Method '{0}' in type '{1}' does not return a value", identifier, GetTypeName(methodInfo.DeclaringType));
					}
					return Expression.Call(instance, methodInfo, array);
				}
				default:
					throw ParseError(pos, "Ambiguous invocation of method '{0}' in type '{1}'", identifier, GetTypeName(type));
				}
			}
			MemberInfo memberInfo = FindPropertyOrField(type, identifier, instance == null);
			if ((object)memberInfo == null)
			{
				throw ParseError(pos, "No property or field '{0}' exists in type '{1}'", identifier, GetTypeName(type));
			}
			if (!(memberInfo is PropertyInfo))
			{
				return Expression.Field(instance, (FieldInfo)memberInfo);
			}
			return Expression.Property(instance, (PropertyInfo)memberInfo);
		}

		private static Type FindGenericType(Type generic, Type type)
		{
			while ((object)type != null && (object)type != typeof(object))
			{
				if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == generic)
				{
					return type;
				}
				if (generic.IsInterface)
				{
					Type[] interfaces = type.GetInterfaces();
					foreach (Type type2 in interfaces)
					{
						Type type3 = FindGenericType(generic, type2);
						if ((object)type3 != null)
						{
							return type3;
						}
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		private Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
		{
			ParameterExpression parameterExpression = it;
			ParameterExpression parameterExpression2 = (it = Expression.Parameter(elementType, ""));
			Expression[] array = ParseArgumentList();
			it = parameterExpression;
			if (FindMethod(typeof(IEnumerableSignatures), methodName, staticAccess: false, array, out var method) != 1)
			{
				throw ParseError(errorPos, "No applicable aggregate method '{0}' exists", methodName);
			}
			return Expression.Call(typeArguments: (!(method.Name == "Min") && !(method.Name == "Max")) ? new Type[1] { elementType } : new Type[2]
			{
				elementType,
				array[0].Type
			}, arguments: (array.Length != 0) ? new Expression[2]
			{
				instance,
				Expression.Lambda(array[0], parameterExpression2)
			} : new Expression[1] { instance }, type: typeof(Enumerable), methodName: method.Name);
		}

		private Expression[] ParseArgumentList()
		{
			ValidateToken(TokenId.OpenParen, "'(' expected");
			NextToken();
			Expression[] result = ((token.id != TokenId.CloseParen) ? ParseArguments() : new Expression[0]);
			ValidateToken(TokenId.CloseParen, "')' or ',' expected");
			NextToken();
			return result;
		}

		private Expression[] ParseArguments()
		{
			List<Expression> list = new List<Expression>();
			while (true)
			{
				list.Add(ParseExpression());
				if (token.id != TokenId.Comma)
				{
					break;
				}
				NextToken();
			}
			return list.ToArray();
		}

		private Expression ParseElementAccess(Expression expr)
		{
			int pos = token.pos;
			ValidateToken(TokenId.OpenBracket, "'(' expected");
			NextToken();
			Expression[] array = ParseArguments();
			ValidateToken(TokenId.CloseBracket, "']' or ',' expected");
			NextToken();
			if (expr.Type.IsArray)
			{
				if (expr.Type.GetArrayRank() != 1 || array.Length != 1)
				{
					throw ParseError(pos, "Indexing of multi-dimensional arrays is not supported");
				}
				Expression expression = PromoteExpression(array[0], typeof(int), exact: true);
				if (expression == null)
				{
					throw ParseError(pos, "Array index must be an integer expression");
				}
				return Expression.ArrayIndex(expr, expression);
			}
			MethodBase method;
			return FindIndexer(expr.Type, array, out method) switch
			{
				0 => throw ParseError(pos, "No applicable indexer exists in type '{0}'", GetTypeName(expr.Type)), 
				1 => Expression.Call(expr, (MethodInfo)method, array), 
				_ => throw ParseError(pos, "Ambiguous invocation of indexer in type '{0}'", GetTypeName(expr.Type)), 
			};
		}

		private static bool IsPredefinedType(Type type)
		{
			Type[] array = predefinedTypes;
			for (int i = 0; i < array.Length; i++)
			{
				if ((object)array[i] == type)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsNullableType(Type type)
		{
			if (type.IsGenericType)
			{
				return (object)type.GetGenericTypeDefinition() == typeof(Nullable<>);
			}
			return false;
		}

		private static Type GetNonNullableType(Type type)
		{
			if (!IsNullableType(type))
			{
				return type;
			}
			return type.GetGenericArguments()[0];
		}

		private static string GetTypeName(Type type)
		{
			Type nonNullableType = GetNonNullableType(type);
			string text = nonNullableType.Name;
			if ((object)type != nonNullableType)
			{
				text += "?";
			}
			return text;
		}

		private static bool IsNumericType(Type type)
		{
			return GetNumericTypeKind(type) != 0;
		}

		private static bool IsSignedIntegralType(Type type)
		{
			return GetNumericTypeKind(type) == 2;
		}

		private static bool IsUnsignedIntegralType(Type type)
		{
			return GetNumericTypeKind(type) == 3;
		}

		private static int GetNumericTypeKind(Type type)
		{
			type = GetNonNullableType(type);
			if (type.IsEnum)
			{
				return 0;
			}
			switch (Type.GetTypeCode(type))
			{
			case TypeCode.Char:
			case TypeCode.Single:
			case TypeCode.Double:
			case TypeCode.Decimal:
				return 1;
			case TypeCode.SByte:
			case TypeCode.Int16:
			case TypeCode.Int32:
			case TypeCode.Int64:
				return 2;
			case TypeCode.Byte:
			case TypeCode.UInt16:
			case TypeCode.UInt32:
			case TypeCode.UInt64:
				return 3;
			default:
				return 0;
			}
		}

		private static bool IsEnumType(Type type)
		{
			return GetNonNullableType(type).IsEnum;
		}

		private void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos)
		{
			Expression[] array = new Expression[1] { expr };
			if (FindMethod(signatures, "F", staticAccess: false, array, out var _) != 1)
			{
				throw ParseError(errorPos, "Operator '{0}' incompatible with operand type '{1}'", opName, GetTypeName(array[0].Type));
			}
			expr = array[0];
		}

		private void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos)
		{
			Expression[] array = new Expression[2] { left, right };
			if (FindMethod(signatures, "F", staticAccess: false, array, out var _) != 1)
			{
				throw IncompatibleOperandsError(opName, left, right, errorPos);
			}
			left = array[0];
			right = array[1];
		}

		private Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos)
		{
			return ParseError(pos, "Operator '{0}' incompatible with operand types '{1}' and '{2}'", opName, GetTypeName(left.Type), GetTypeName(right.Type));
		}

		private MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)
		{
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
			foreach (Type item in SelfAndBaseTypes(type))
			{
				MemberInfo[] array = item.FindMembers(MemberTypes.Field | MemberTypes.Property, bindingAttr, Type.FilterNameIgnoreCase, memberName);
				if (array.Length != 0)
				{
					return array[0];
				}
			}
			return null;
		}

		private int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)
		{
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
			foreach (Type item in SelfAndBaseTypes(type))
			{
				MemberInfo[] source = item.FindMembers(MemberTypes.Method, bindingAttr, Type.FilterNameIgnoreCase, methodName);
				int num = FindBestMethod(source.Cast<MethodBase>(), args, out method);
				if (num != 0)
				{
					return num;
				}
			}
			method = null;
			return 0;
		}

		private int FindIndexer(Type type, Expression[] args, out MethodBase method)
		{
			foreach (Type item in SelfAndBaseTypes(type))
			{
				MemberInfo[] defaultMembers = item.GetDefaultMembers();
				if (defaultMembers.Length != 0)
				{
					IEnumerable<MethodBase> methods = from m in defaultMembers.OfType<PropertyInfo>().Select((Func<PropertyInfo, MethodBase>)((PropertyInfo p) => p.GetGetMethod()))
						where (object)m != null
						select m;
					int num = FindBestMethod(methods, args, out method);
					if (num != 0)
					{
						return num;
					}
				}
			}
			method = null;
			return 0;
		}

		private static IEnumerable<Type> SelfAndBaseTypes(Type type)
		{
			if (type.IsInterface)
			{
				List<Type> list = new List<Type>();
				AddInterface(list, type);
				return list;
			}
			return SelfAndBaseClasses(type);
		}

		private static IEnumerable<Type> SelfAndBaseClasses(Type type)
		{
			while ((object)type != null)
			{
				yield return type;
				type = type.BaseType;
			}
		}

		private static void AddInterface(List<Type> types, Type type)
		{
			if (!types.Contains(type))
			{
				types.Add(type);
				Type[] interfaces = type.GetInterfaces();
				foreach (Type type2 in interfaces)
				{
					AddInterface(types, type2);
				}
			}
		}

		private int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method)
		{
			MethodData[] applicable = (from m in methods
				select new MethodData
				{
					MethodBase = m,
					Parameters = m.GetParameters()
				} into m
				where IsApplicable(m, args)
				select m).ToArray();
			if (applicable.Length > 1)
			{
				applicable = applicable.Where((MethodData m) => applicable.All((MethodData n) => m == n || IsBetterThan(args, m, n))).ToArray();
			}
			if (applicable.Length == 1)
			{
				MethodData methodData = applicable[0];
				for (int i = 0; i < args.Length; i++)
				{
					args[i] = methodData.Args[i];
				}
				method = methodData.MethodBase;
			}
			else
			{
				method = null;
			}
			return applicable.Length;
		}

		private bool IsApplicable(MethodData method, Expression[] args)
		{
			if (method.Parameters.Length != args.Length)
			{
				return false;
			}
			Expression[] array = new Expression[args.Length];
			for (int i = 0; i < args.Length; i++)
			{
				ParameterInfo parameterInfo = method.Parameters[i];
				if (parameterInfo.IsOut)
				{
					return false;
				}
				Expression expression = PromoteExpression(args[i], parameterInfo.ParameterType, exact: false);
				if (expression == null)
				{
					return false;
				}
				array[i] = expression;
			}
			method.Args = array;
			return true;
		}

		private Expression PromoteExpression(Expression expr, Type type, bool exact)
		{
			if ((object)expr.Type == type)
			{
				return expr;
			}
			if (expr is ConstantExpression)
			{
				ConstantExpression constantExpression = (ConstantExpression)expr;
				string value;
				if (constantExpression == nullLiteral)
				{
					if (!type.IsValueType || IsNullableType(type))
					{
						return Expression.Constant(null, type);
					}
				}
				else if (literals.TryGetValue(constantExpression, out value))
				{
					Type nonNullableType = GetNonNullableType(type);
					object obj = null;
					switch (Type.GetTypeCode(constantExpression.Type))
					{
					case TypeCode.Int32:
					case TypeCode.UInt32:
					case TypeCode.Int64:
					case TypeCode.UInt64:
						obj = ParseNumber(value, nonNullableType);
						break;
					case TypeCode.Double:
						if ((object)nonNullableType == typeof(decimal))
						{
							obj = ParseNumber(value, nonNullableType);
						}
						break;
					case TypeCode.String:
						obj = ParseEnum(value, nonNullableType);
						break;
					}
					if (obj != null)
					{
						return Expression.Constant(obj, type);
					}
				}
			}
			if (IsCompatibleWith(expr.Type, type))
			{
				if (type.IsValueType || exact)
				{
					return Expression.Convert(expr, type);
				}
				return expr;
			}
			return null;
		}

		private static object ParseNumber(string text, Type type)
		{
			switch (Type.GetTypeCode(GetNonNullableType(type)))
			{
			case TypeCode.SByte:
			{
				if (sbyte.TryParse(text, out var result6))
				{
					return result6;
				}
				break;
			}
			case TypeCode.Byte:
			{
				if (byte.TryParse(text, out var result10))
				{
					return result10;
				}
				break;
			}
			case TypeCode.Int16:
			{
				if (short.TryParse(text, out var result2))
				{
					return result2;
				}
				break;
			}
			case TypeCode.UInt16:
			{
				if (ushort.TryParse(text, out var result8))
				{
					return result8;
				}
				break;
			}
			case TypeCode.Int32:
			{
				if (int.TryParse(text, out var result4))
				{
					return result4;
				}
				break;
			}
			case TypeCode.UInt32:
			{
				if (uint.TryParse(text, out var result11))
				{
					return result11;
				}
				break;
			}
			case TypeCode.Int64:
			{
				if (long.TryParse(text, out var result9))
				{
					return result9;
				}
				break;
			}
			case TypeCode.UInt64:
			{
				if (ulong.TryParse(text, out var result7))
				{
					return result7;
				}
				break;
			}
			case TypeCode.Single:
			{
				if (float.TryParse(text, out var result5))
				{
					return result5;
				}
				break;
			}
			case TypeCode.Double:
			{
				if (double.TryParse(text, out var result3))
				{
					return result3;
				}
				break;
			}
			case TypeCode.Decimal:
			{
				if (decimal.TryParse(text, out var result))
				{
					return result;
				}
				break;
			}
			}
			return null;
		}

		private static object ParseEnum(string name, Type type)
		{
			if (type.IsEnum)
			{
				MemberInfo[] array = type.FindMembers(MemberTypes.Field, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public, Type.FilterNameIgnoreCase, name);
				if (array.Length != 0)
				{
					return ((FieldInfo)array[0]).GetValue(null);
				}
			}
			return null;
		}

		private static bool IsCompatibleWith(Type source, Type target)
		{
			if ((object)source == target)
			{
				return true;
			}
			if (!target.IsValueType)
			{
				return target.IsAssignableFrom(source);
			}
			Type nonNullableType = GetNonNullableType(source);
			Type nonNullableType2 = GetNonNullableType(target);
			if ((object)nonNullableType != source && (object)nonNullableType2 == target)
			{
				return false;
			}
			TypeCode typeCode = (nonNullableType.IsEnum ? TypeCode.Object : Type.GetTypeCode(nonNullableType));
			TypeCode typeCode2 = (nonNullableType2.IsEnum ? TypeCode.Object : Type.GetTypeCode(nonNullableType2));
			switch (typeCode)
			{
			case TypeCode.SByte:
				switch (typeCode2)
				{
				case TypeCode.SByte:
				case TypeCode.Int16:
				case TypeCode.Int32:
				case TypeCode.Int64:
				case TypeCode.Single:
				case TypeCode.Double:
				case TypeCode.Decimal:
					return true;
				}
				break;
			case TypeCode.Byte:
				if ((uint)(typeCode2 - 6) <= 9u)
				{
					return true;
				}
				break;
			case TypeCode.Int16:
				switch (typeCode2)
				{
				case TypeCode.Int16:
				case TypeCode.Int32:
				case TypeCode.Int64:
				case TypeCode.Single:
				case TypeCode.Double:
				case TypeCode.Decimal:
					return true;
				}
				break;
			case TypeCode.UInt16:
				if ((uint)(typeCode2 - 8) <= 7u)
				{
					return true;
				}
				break;
			case TypeCode.Int32:
				switch (typeCode2)
				{
				case TypeCode.Int32:
				case TypeCode.Int64:
				case TypeCode.Single:
				case TypeCode.Double:
				case TypeCode.Decimal:
					return true;
				}
				break;
			case TypeCode.UInt32:
				if ((uint)(typeCode2 - 10) <= 5u)
				{
					return true;
				}
				break;
			case TypeCode.Int64:
				if (typeCode2 == TypeCode.Int64 || (uint)(typeCode2 - 13) <= 2u)
				{
					return true;
				}
				break;
			case TypeCode.UInt64:
				if ((uint)(typeCode2 - 12) <= 3u)
				{
					return true;
				}
				break;
			case TypeCode.Single:
				if ((uint)(typeCode2 - 13) <= 1u)
				{
					return true;
				}
				break;
			default:
				if ((object)nonNullableType == nonNullableType2)
				{
					return true;
				}
				break;
			}
			return false;
		}

		private static bool IsBetterThan(Expression[] args, MethodData m1, MethodData m2)
		{
			bool result = false;
			for (int i = 0; i < args.Length; i++)
			{
				int num = CompareConversions(args[i].Type, m1.Parameters[i].ParameterType, m2.Parameters[i].ParameterType);
				if (num < 0)
				{
					return false;
				}
				if (num > 0)
				{
					result = true;
				}
			}
			return result;
		}

		private static int CompareConversions(Type s, Type t1, Type t2)
		{
			if ((object)t1 == t2)
			{
				return 0;
			}
			if ((object)s == t1)
			{
				return 1;
			}
			if ((object)s == t2)
			{
				return -1;
			}
			bool flag = IsCompatibleWith(t1, t2);
			bool flag2 = IsCompatibleWith(t2, t1);
			if (flag && !flag2)
			{
				return 1;
			}
			if (flag2 && !flag)
			{
				return -1;
			}
			if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2))
			{
				return 1;
			}
			if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1))
			{
				return -1;
			}
			return 0;
		}

		private Expression GenerateEqual(Expression left, Expression right)
		{
			return Expression.Equal(left, right);
		}

		private Expression GenerateNotEqual(Expression left, Expression right)
		{
			return Expression.NotEqual(left, right);
		}

		private Expression GenerateGreaterThan(Expression left, Expression right)
		{
			if ((object)left.Type == typeof(string))
			{
				return Expression.GreaterThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0));
			}
			return Expression.GreaterThan(left, right);
		}

		private Expression GenerateGreaterThanEqual(Expression left, Expression right)
		{
			if ((object)left.Type == typeof(string))
			{
				return Expression.GreaterThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0));
			}
			return Expression.GreaterThanOrEqual(left, right);
		}

		private Expression GenerateLessThan(Expression left, Expression right)
		{
			if ((object)left.Type == typeof(string))
			{
				return Expression.LessThan(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0));
			}
			return Expression.LessThan(left, right);
		}

		private Expression GenerateLessThanEqual(Expression left, Expression right)
		{
			if ((object)left.Type == typeof(string))
			{
				return Expression.LessThanOrEqual(GenerateStaticMethodCall("Compare", left, right), Expression.Constant(0));
			}
			return Expression.LessThanOrEqual(left, right);
		}

		private Expression GenerateAdd(Expression left, Expression right)
		{
			if ((object)left.Type == typeof(string) && (object)right.Type == typeof(string))
			{
				return GenerateStaticMethodCall("Concat", left, right);
			}
			return Expression.Add(left, right);
		}

		private Expression GenerateSubtract(Expression left, Expression right)
		{
			return Expression.Subtract(left, right);
		}

		private Expression GenerateStringConcat(Expression left, Expression right)
		{
			return Expression.Call(null, typeof(string).GetMethod("Concat", new Type[2]
			{
				typeof(object),
				typeof(object)
			}), new Expression[2] { left, right });
		}

		private MethodInfo GetStaticMethod(string methodName, Expression left, Expression right)
		{
			return left.Type.GetMethod(methodName, new Type[2] { left.Type, right.Type });
		}

		private Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right)
		{
			return Expression.Call(null, GetStaticMethod(methodName, left, right), new Expression[2] { left, right });
		}

		private void SetTextPos(int pos)
		{
			textPos = pos;
			ch = ((textPos < textLen) ? text[textPos] : '\0');
		}

		private void NextChar()
		{
			if (textPos < textLen)
			{
				textPos++;
			}
			ch = ((textPos < textLen) ? text[textPos] : '\0');
		}

		private void NextToken()
		{
			while (char.IsWhiteSpace(ch))
			{
				NextChar();
			}
			int num = textPos;
			TokenId id;
			switch (ch)
			{
			case '!':
				NextChar();
				if (ch == '=')
				{
					NextChar();
					id = TokenId.ExclamationEqual;
				}
				else
				{
					id = TokenId.Exclamation;
				}
				break;
			case '%':
				NextChar();
				id = TokenId.Percent;
				break;
			case '&':
				NextChar();
				if (ch == '&')
				{
					NextChar();
					id = TokenId.DoubleAmphersand;
				}
				else
				{
					id = TokenId.Amphersand;
				}
				break;
			case '(':
				NextChar();
				id = TokenId.OpenParen;
				break;
			case ')':
				NextChar();
				id = TokenId.CloseParen;
				break;
			case '*':
				NextChar();
				id = TokenId.Asterisk;
				break;
			case '+':
				NextChar();
				id = TokenId.Plus;
				break;
			case ',':
				NextChar();
				id = TokenId.Comma;
				break;
			case '-':
				NextChar();
				id = TokenId.Minus;
				break;
			case '.':
				NextChar();
				id = TokenId.Dot;
				break;
			case '/':
				NextChar();
				id = TokenId.Slash;
				break;
			case ':':
				NextChar();
				id = TokenId.Colon;
				break;
			case '<':
				NextChar();
				if (ch == '=')
				{
					NextChar();
					id = TokenId.LessThanEqual;
				}
				else if (ch == '>')
				{
					NextChar();
					id = TokenId.LessGreater;
				}
				else
				{
					id = TokenId.LessThan;
				}
				break;
			case '=':
				NextChar();
				if (ch == '=')
				{
					NextChar();
					id = TokenId.DoubleEqual;
				}
				else
				{
					id = TokenId.Equal;
				}
				break;
			case '>':
				NextChar();
				if (ch == '=')
				{
					NextChar();
					id = TokenId.GreaterThanEqual;
				}
				else
				{
					id = TokenId.GreaterThan;
				}
				break;
			case '?':
				NextChar();
				id = TokenId.Question;
				break;
			case '[':
				NextChar();
				id = TokenId.OpenBracket;
				break;
			case ']':
				NextChar();
				id = TokenId.CloseBracket;
				break;
			case '|':
				NextChar();
				if (ch == '|')
				{
					NextChar();
					id = TokenId.DoubleBar;
				}
				else
				{
					id = TokenId.Bar;
				}
				break;
			case '"':
			case '\'':
			{
				char c = ch;
				do
				{
					NextChar();
					while (textPos < textLen && ch != c)
					{
						NextChar();
					}
					if (textPos == textLen)
					{
						throw ParseError(textPos, "Unterminated string literal");
					}
					NextChar();
				}
				while (ch == c);
				id = TokenId.StringLiteral;
				break;
			}
			default:
				if (char.IsLetter(ch) || ch == '@' || ch == '_')
				{
					do
					{
						NextChar();
					}
					while (char.IsLetterOrDigit(ch) || ch == '_');
					id = TokenId.Identifier;
				}
				else if (char.IsDigit(ch))
				{
					id = TokenId.IntegerLiteral;
					do
					{
						NextChar();
					}
					while (char.IsDigit(ch));
					if (ch == '.')
					{
						id = TokenId.RealLiteral;
						NextChar();
						ValidateDigit();
						do
						{
							NextChar();
						}
						while (char.IsDigit(ch));
					}
					if (ch == 'E' || ch == 'e')
					{
						id = TokenId.RealLiteral;
						NextChar();
						if (ch == '+' || ch == '-')
						{
							NextChar();
						}
						ValidateDigit();
						do
						{
							NextChar();
						}
						while (char.IsDigit(ch));
					}
					if (ch == 'F' || ch == 'f')
					{
						NextChar();
					}
				}
				else
				{
					if (textPos != textLen)
					{
						throw ParseError(textPos, "Syntax error '{0}'", ch);
					}
					id = TokenId.End;
				}
				break;
			}
			token.id = id;
			token.text = text.Substring(num, textPos - num);
			token.pos = num;
		}

		private bool TokenIdentifierIs(string id)
		{
			if (token.id == TokenId.Identifier)
			{
				return string.Equals(id, token.text, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private string GetIdentifier()
		{
			ValidateToken(TokenId.Identifier, "Identifier expected");
			string text = token.text;
			if (text.Length > 1 && text[0] == '@')
			{
				text = text.Substring(1);
			}
			return text;
		}

		private void ValidateDigit()
		{
			if (!char.IsDigit(ch))
			{
				throw ParseError(textPos, "Digit expected");
			}
		}

		private void ValidateToken(TokenId t, string errorMessage)
		{
			if (token.id != t)
			{
				throw ParseError(errorMessage);
			}
		}

		private void ValidateToken(TokenId t)
		{
			if (token.id != t)
			{
				throw ParseError("Syntax error");
			}
		}

		private Exception ParseError(string format, params object[] args)
		{
			return ParseError(token.pos, format, args);
		}

		private Exception ParseError(int pos, string format, params object[] args)
		{
			return new ParseException(string.Format(CultureInfo.CurrentCulture, format, args), pos);
		}

		private static Dictionary<string, object> CreateKeywords()
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
			dictionary.Add("true", trueLiteral);
			dictionary.Add("false", falseLiteral);
			dictionary.Add("null", nullLiteral);
			dictionary.Add(keywordIt, keywordIt);
			dictionary.Add(keywordIif, keywordIif);
			dictionary.Add(keywordNew, keywordNew);
			Type[] array = predefinedTypes;
			foreach (Type type in array)
			{
				dictionary.Add(type.Name, type);
			}
			return dictionary;
		}
	}
	internal static class Res
	{
		public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once";

		public const string ExpressionTypeMismatch = "Expression of type '{0}' expected";

		public const string ExpressionExpected = "Expression expected";

		public const string InvalidCharacterLiteral = "Character literal must contain exactly one character";

		public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'";

		public const string InvalidRealLiteral = "Invalid real literal '{0}'";

		public const string UnknownIdentifier = "Unknown identifier '{0}'";

		public const string NoItInScope = "No 'it' is in scope";

		public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments";

		public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'";

		public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other";

		public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";

		public const string MissingAsClause = "Expression is missing an 'as' clause";

		public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression";

		public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form";

		public const string NoMatchingConstructor = "No matching constructor in type '{0}'";

		public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor";

		public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'";

		public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";

		public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible";

		public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value";

		public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'";

		public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'";

		public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists";

		public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported";

		public const string InvalidIndex = "Array index must be an integer expression";

		public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";

		public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'";

		public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'";

		public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'";

		public const string UnterminatedStringLiteral = "Unterminated string literal";

		public const string InvalidCharacter = "Syntax error '{0}'";

		public const string DigitExpected = "Digit expected";

		public const string SyntaxError = "Syntax error";

		public const string TokenExpected = "{0} expected";

		public const string ParseExceptionFormat = "{0} (at index {1})";

		public const string ColonExpected = "':' expected";

		public const string OpenParenExpected = "'(' expected";

		public const string CloseParenOrOperatorExpected = "')' or operator expected";

		public const string CloseParenOrCommaExpected = "')' or ',' expected";

		public const string DotOrOpenParenExpected = "'.' or '(' expected";

		public const string OpenBracketExpected = "'[' expected";

		public const string CloseBracketOrCommaExpected = "']' or ',' expected";

		public const string IdentifierExpected = "Identifier expected";
	}
}
namespace SimpleJSON
{
	public enum JSONNodeType
	{
		Array = 1,
		Object = 2,
		String = 3,
		Number = 4,
		NullValue = 5,
		Boolean = 6,
		None = 7,
		Custom = 255
	}
	public enum JSONTextMode
	{
		Compact,
		Indent
	}
	public abstract class JSONNode
	{
		public struct Enumerator
		{
			private enum Type
			{
				None,
				Array,
				Object
			}

			private Type type;

			private Dictionary<string, JSONNode>.Enumerator m_Object;

			private List<JSONNode>.Enumerator m_Array;

			public bool IsValid => type != Type.None;

			public KeyValuePair<string, JSONNode> Current
			{
				get
				{
					if (type == Type.Array)
					{
						return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
					}
					if (type == Type.Object)
					{
						return m_Object.Current;
					}
					return new KeyValuePair<string, JSONNode>(string.Empty, null);
				}
			}

			public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
			{
				type = Type.Array;
				m_Object = default(Dictionary<string, JSONNode>.Enumerator);
				m_Array = aArrayEnum;
			}

			public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
			{
				type = Type.Object;
				m_Object = aDictEnum;
				m_Array = default(List<JSONNode>.Enumerator);
			}

			public bool MoveNext()
			{
				if (type == Type.Array)
				{
					return m_Array.MoveNext();
				}
				if (type == Type.Object)
				{
					return m_Object.MoveNext();
				}
				return false;
			}
		}

		public struct ValueEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Value;

			public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public ValueEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public ValueEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public struct KeyEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Key;

			public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public KeyEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public KeyEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable
		{
			private JSONNode m_Node;

			private Enumerator m_Enumerator;

			public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current;

			object IEnumerator.Current => m_Enumerator.Current;

			internal LinqEnumerator(JSONNode aNode)
			{
				m_Node = aNode;
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public void Dispose()
			{
				m_Node = null;
				m_Enumerator = default(Enumerator);
			}

			public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}

			public void Reset()
			{
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}
		}

		public static bool forceASCII;

		[ThreadStatic]
		private static StringBuilder m_EscapeBuilder;

		public abstract JSONNodeType Tag { get; }

		public virtual JSONNode this[int aIndex]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual JSONNode this[string aKey]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Value
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual int Count => 0;

		public virtual bool IsNumber => false;

		public virtual bool IsString => false;

		public virtual bool IsBoolean => false;

		public virtual bool IsNull => false;

		public virtual bool IsArray => false;

		public virtual bool IsObject => false;

		public virtual bool Inline
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public virtual IEnumerable<JSONNode> Children
		{
			get
			{
				yield break;
			}
		}

		public IEnumerable<JSONNode> DeepChildren
		{
			get
			{
				foreach (JSONNode child in Children)
				{
					foreach (JSONNode deepChild in child.DeepChildren)
					{
						yield return deepChild;
					}
				}
			}
		}

		public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this);

		public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator());

		public ValueEnumerator Values => new ValueEnumerator(GetEnumerator());

		public virtual double AsDouble
		{
			get
			{
				double result = 0.0;
				if (double.TryParse(Value, out result))
				{
					return result;
				}
				return 0.0;
			}
			set
			{
				Value = value.ToString();
			}
		}

		public virtual int AsInt
		{
			get
			{
				return (int)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual float AsFloat
		{
			get
			{
				return (float)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual bool AsBool
		{
			get
			{
				bool result = false;
				if (bool.TryParse(Value, out result))
				{
					return result;
				}
				return !string.IsNullOrEmpty(Value);
			}
			set
			{
				Value = (value ? "true" : "false");
			}
		}

		public virtual JSONArray AsArray => this as JSONArray;

		public virtual JSONObject AsObject => this as JSONObject;

		internal static StringBuilder EscapeBuilder
		{
			get
			{
				if (m_EscapeBuilder == null)
				{
					m_EscapeBuilder = new StringBuilder();
				}
				return m_EscapeBuilder;
			}
		}

		public virtual void Add(string aKey, JSONNode aItem)
		{
		}

		public virtual void Add(JSONNode aItem)
		{
			Add("", aItem);
		}

		public virtual JSONNode Remove(string aKey)
		{
			return null;
		}

		public virtual JSONNode Remove(int aIndex)
		{
			return null;
		}

		public virtual JSONNode Remove(JSONNode aNode)
		{
			return aNode;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact);
			return stringBuilder.ToString();
		}

		public virtual string ToString(int aIndent)
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent);
			return stringBuilder.ToString();
		}

		internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);

		public abstract Enumerator GetEnumerator();

		public static implicit operator JSONNode(string s)
		{
			return new JSONString(s);
		}

		public static implicit operator string(JSONNode d)
		{
			if (!(d == null))
			{
				return d.Value;
			}
			return null;
		}

		public static implicit operator JSONNode(double n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator double(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsDouble;
			}
			return 0.0;
		}

		public static implicit operator JSONNode(float n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator float(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsFloat;
			}
			return 0f;
		}

		public static implicit operator JSONNode(int n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator int(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsInt;
			}
			return 0;
		}

		public static implicit operator JSONNode(bool b)
		{
			return new JSONBool(b);
		}

		public static implicit operator bool(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsBool;
			}
			return false;
		}

		public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue)
		{
			return aKeyValue.Value;
		}

		public static bool operator ==(JSONNode a, object b)
		{
			if ((object)a == b)
			{
				return true;
			}
			bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator;
			bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator;
			if (flag && flag2)
			{
				return true;
			}
			if (!flag)
			{
				return a.Equals(b);
			}
			return false;
		}

		public static bool operator !=(JSONNode a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		internal static string Escape(string aText)
		{
			StringBuilder escapeBuilder = EscapeBuilder;
			escapeBuilder.Length = 0;
			if (escapeBuilder.Capacity < aText.Length + aText.Length / 10)
			{
				escapeBuilder.Capacity = aText.Length + aText.Length / 10;
			}
			foreach (char c in aText)
			{
				switch (c)
				{
				case '\\':
					escapeBuilder.Append("\\\\");
					continue;
				case '"':
					escapeBuilder.Append("\\\"");
					continue;
				case '\n':
					escapeBuilder.Append("\\n");
					continue;
				case '\r':
					escapeBuilder.Append("\\r");
					continue;
				case '\t':
					escapeBuilder.Append("\\t");
					continue;
				case '\b':
					escapeBuilder.Append("\\b");
					continue;
				case '\f':
					escapeBuilder.Append("\\f");
					continue;
				}
				if (c < ' ' || (forceASCII && c > '\u007f'))
				{
					ushort num = c;
					escapeBuilder.Append("\\u").Append(num.ToString("X4"));
				}
				else
				{
					escapeBuilder.Append(c);
				}
			}
			string result = escapeBuilder.ToString();
			escapeBuilder.Length = 0;
			return result;
		}

		private static void ParseElement(JSONNode ctx, string token, string tokenName, bool quoted)
		{
			if (quoted)
			{
				ctx.Add(tokenName, token);
				return;
			}
			string text = token.ToLower();
			switch (text)
			{
			case "false":
			case "true":
				ctx.Add(tokenName, text == "true");
				return;
			case "null":
				ctx.Add(tokenName, null);
				return;
			}
			if (double.TryParse(token, out var result))
			{
				ctx.Add(tokenName, result);
			}
			else
			{
				ctx.Add(tokenName, token);
			}
		}

		public static JSONNode Parse(string aJSON)
		{
			Stack<JSONNode> stack = new Stack<JSONNode>();
			JSONNode jSONNode = null;
			int i = 0;
			StringBuilder stringBuilder = new StringBuilder();
			string text = "";
			bool flag = false;
			bool flag2 = false;
			for (; i < aJSON.Length; i++)
			{
				switch (aJSON[i])
				{
				case '{':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONObject());
					if (jSONNode != null)
					{
						jSONNode.Add(text, stack.Peek());
					}
					text = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					break;
				case '[':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONArray());
					if (jSONNode != null)
					{
						jSONNode.Add(text, stack.Peek());
					}
					text = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					break;
				case ']':
				case '}':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stack.Count == 0)
					{
						throw new Exception("JSON Parse: Too many closing brackets");
					}
					stack.Pop();
					if (stringBuilder.Length > 0 || flag2)
					{
						ParseElement(jSONNode, stringBuilder.ToString(), text, flag2);
						flag2 = false;
					}
					text = "";
					stringBuilder.Length = 0;
					if (stack.Count > 0)
					{
						jSONNode = stack.Peek();
					}
					break;
				case ':':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					text = stringBuilder.ToString();
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '"':
					flag = !flag;
					flag2 = flag2 || flag;
					break;
				case ',':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stringBuilder.Length > 0 || flag2)
					{
						ParseElement(jSONNode, stringBuilder.ToString(), text, flag2);
						flag2 = false;
					}
					text = "";
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '\t':
				case ' ':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				case '\\':
					i++;
					if (flag)
					{
						char c = aJSON[i];
						switch (c)
						{
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'u':
						{
							string s = aJSON.Substring(i + 1, 4);
							stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier));
							i += 4;
							break;
						}
						default:
							stringBuilder.Append(c);
							break;
						}
					}
					break;
				default:
					stringBuilder.Append(aJSON[i]);
					break;
				case '\n':
				case '\r':
					break;
				}
			}
			if (flag)
			{
				throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
			}
			return jSONNode;
		}
	}
	public class JSONArray : JSONNode
	{
		private List<JSONNode> m_List = new List<JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Array;

		public override bool IsArray => true;

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					return new JSONLazyCreator(this);
				}
				return m_List[aIndex];
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					m_List.Add(value);
				}
				else
				{
					m_List[aIndex] = value;
				}
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				m_List.Add(value);
			}
		}

		public override int Count => m_List.Count;

		public override IEnumerable<JSONNode> Children
		{
			get
			{
				foreach (JSONNode item in m_List)
				{
					yield return item;
				}
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_List.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			m_List.Add(aItem);
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_List.Count)
			{
				return null;
			}
			JSONNode result = m_List[aIndex];
			m_List.RemoveAt(aIndex);
			return result;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			m_List.Remove(aNode);
			return aNode;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('[');
			int count = m_List.Count;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			for (int i = 0; i < count; i++)
			{
				if (i > 0)
				{
					aSB.Append(',');
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append(']');
		}
	}
	public class JSONObject : JSONNode
	{
		private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Object;

		public override bool IsObject => true;

		public override JSONNode this[string aKey]
		{
			get
			{
				if (m_Dict.ContainsKey(aKey))
				{
					return m_Dict[aKey];
				}
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = value;
				}
				else
				{
					m_Dict.Add(aKey, value);
				}
			}
		}

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_Dict.Count)
				{
					return null;
				}
				return m_Dict.ElementAt(aIndex).Value;
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex >= 0 && aIndex < m_Dict.Count)
				{
					string key = m_Dict.ElementAt(aIndex).Key;
					m_Dict[key] = value;
				}
			}
		}

		public override int Count => m_Dict.Count;

		public override IEnumerable<JSONNode> Children
		{
			get
			{
				foreach (KeyValuePair<string, JSONNode> item in m_Dict)
				{
					yield return item.Value;
				}
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_Dict.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			if (!string.IsNullOrEmpty(aKey))
			{
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = aItem;
				}
				else
				{
					m_Dict.Add(aKey, aItem);
				}
			}
			else
			{
				m_Dict.Add(Guid.NewGuid().ToString(), aItem);
			}
		}

		public override JSONNode Remove(string aKey)
		{
			if (!m_Dict.ContainsKey(aKey))
			{
				return null;
			}
			JSONNode result = m_Dict[aKey];
			m_Dict.Remove(aKey);
			return result;
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_Dict.Count)
			{
				return null;
			}
			KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex);
			m_Dict.Remove(keyValuePair.Key);
			return keyValuePair.Value;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			try
			{
				KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First();
				m_Dict.Remove(keyValuePair.Key);
				return aNode;
			}
			catch
			{
				return null;
			}
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('{');
			bool flag = true;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				if (!flag)
				{
					aSB.Append(',');
				}
				flag = false;
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"');
				if (aMode == JSONTextMode.Compact)
				{
					aSB.Append(':');
				}
				else
				{
					aSB.Append(" : ");
				}
				item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append('}');
		}
	}
	public class JSONString : JSONNode
	{
		private string m_Data;

		public override JSONNodeType Tag => JSONNodeType.String;

		public override bool IsString => true;

		public override string Value
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONString(string aData)
		{
			m_Data = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"');
		}

		public override bool Equals(object obj)
		{
			if (base.Equals(obj))
			{
				return true;
			}
			if (obj is string text)
			{
				return m_Data == text;
			}
			JSONString jSONString = obj as JSONString;
			if (jSONString != null)
			{
				return m_Data == jSONString.m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONNumber : JSONNode
	{
		private double m_Data;

		public override JSONNodeType Tag => JSONNodeType.Number;

		public override bool IsNumber => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (double.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override double AsDouble
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONNumber(double aData)
		{
			m_Data = aData;
		}

		public JSONNumber(string aData)
		{
			Value = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data);
		}

		private static bool IsNumeric(object value)
		{
			if (!(value is int) && !(value is uint) && !(value is float) && !(value is double) && !(value is decimal) && !(value is long) && !(value is ulong) && !(value is short) && !(value is ushort) && !(value is sbyte))
			{
				return value is byte;
			}
			return true;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (base.Equals(obj))
			{
				return true;
			}
			JSONNumber jSONNumber = obj as JSONNumber;
			if (jSONNumber != null)
			{
				return m_Data == jSONNumber.m_Data;
			}
			if (IsNumeric(obj))
			{
				return Convert.ToDouble(obj) == m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONBool : JSONNode
	{
		private bool m_Data;

		public override JSONNodeType Tag => JSONNodeType.Boolean;

		public override bool IsBoolean => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (bool.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONBool(bool aData)
		{
			m_Data = aData;
		}

		public JSONBool(string aData)
		{
			Value = aData;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data ? "true" : "false");
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is bool)
			{
				return m_Data == (bool)obj;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}
	}
	public class JSONNull : JSONNode
	{
		private static JSONNull m_StaticInstance = new JSONNull();

		public static bool reuseSameInstance = true;

		public override JSONNodeType Tag => JSONNodeType.NullValue;

		public override bool IsNull => true;

		public override string Value
		{
			get
			{
				return "null";
			}
			set
			{
			}
		}

		public override bool AsBool
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public static JSONNull CreateOrGet()
		{
			if (reuseSameInstance)
			{
				return m_StaticInstance;
			}
			return new JSONNull();
		}

		private JSONNull()
		{
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public override bool Equals(object obj)
		{
			if ((object)this == obj)
			{
				return true;
			}
			return obj is JSONNull;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	internal class JSONLazyCreator : JSONNode
	{
		private JSONNode m_Node;

		private string m_Key;

		public override JSONNodeType Tag => JSONNodeType.None;

		public override JSONNode this[int aIndex]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				JSONArray jSONArray = new JSONArray();
				jSONArray.Add(value);
				Set(jSONArray);
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				JSONObject jSONObject = new JSONObject();
				jSONObject.Add(aKey, value);
				Set(jSONObject);
			}
		}

		public override int AsInt
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override float AsFloat
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0f;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override double AsDouble
		{
			get
			{
				JSONNumber aVal = new JSONNumber(0.0);
				Set(aVal);
				return 0.0;
			}
			set
			{
				JSONNumber aVal = new JSONNumber(value);
				Set(aVal);
			}
		}

		public override bool AsBool
		{
			get
			{
				JSONBool aVal = new JSONBool(aData: false);
				Set(aVal);
				return false;
			}
			set
			{
				JSONBool aVal = new JSONBool(value);
				Set(aVal);
			}
		}

		public override JSONArray AsArray
		{
			get
			{
				JSONArray jSONArray = new JSONArray();
				Set(jSONArray);
				return jSONArray;
			}
		}

		public override JSONObject AsObject
		{
			get
			{
				JSONObject jSONObject = new JSONObject();
				Set(jSONObject);
				return jSONObject;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONLazyCreator(JSONNode aNode)
		{
			m_Node = aNode;
			m_Key = null;
		}

		public JSONLazyCreator(JSONNode aNode, string aKey)
		{
			m_Node = aNode;
			m_Key = aKey;
		}

		private void Set(JSONNode aVal)
		{
			if (m_Key == null)
			{
				m_Node.Add(aVal);
			}
			else
			{
				m_Node.Add(m_Key, aVal);
			}
			m_Node = null;
		}

		public override void Add(JSONNode aItem)
		{
			JSONArray jSONArray = new JSONArray();
			jSONArray.Add(aItem);
			Set(jSONArray);
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			JSONObject jSONObject = new JSONObject();
			jSONObject.Add(aKey, aItem);
			Set(jSONObject);
		}

		public static bool operator ==(JSONLazyCreator a, object b)
		{
			if (b == null)
			{
				return true;
			}
			return (object)a == b;
		}

		public static bool operator !=(JSONLazyCreator a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return true;
			}
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	public static class JSON
	{
		public static JSONNode Parse(string aJSON)
		{
			return JSONNode.Parse(aJSON);
		}
	}
}
namespace XUnity.AutoTranslator.Plugin
{
	internal class SceneLoadInformation
	{
		public SceneInformation ActiveScene { get; set; }

		public List<SceneInformation> LoadedScenes { get; set; }

		public SceneLoadInformation()
		{
			LoadedScenes = new List<SceneInformation>();
			if (UnityFeatures.SupportsSceneManager)
			{
				LoadBySceneManager();
			}
			else
			{
				LoadByApplication();
			}
		}

		public void LoadBySceneManager()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			ActiveScene = new SceneInformation(((Scene)(ref activeScene)).buildIndex, ((Scene)(ref activeScene)).name);
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				LoadedScenes.Add(new SceneInformation(((Scene)(ref sceneAt)).buildIndex, ((Scene)(ref sceneAt)).name));
			}
		}

		public void LoadByApplication()
		{
			ActiveScene = new SceneInformation(Application.loadedLevel, Application.loadedLevelName);
			LoadedScenes.Add(new SceneInformation(Application.loadedLevel, Application.loadedLevelName));
		}
	}
	internal class SceneInformation
	{
		public int Id { get; set; }

		public string Name { get; set; }

		public SceneInformation(int id, string name)
		{
			Id = id;
			Name = name;
		}
	}
}
namespace XUnity.AutoTranslator.Plugin.Utilities
{
	internal static class TranslationScopeHelper
	{
		public static int GetScope(object ui)
		{
			if (Settings.EnableTranslationScoping)
			{
				try
				{
					Component val = (Component)((ui is Component) ? ui : null);
					if (val != null && Object.op_Implicit((Object)(object)val))
					{
						return GetScopeFromComponent(val);
					}
					if (ui is GUIContent)
					{
						return -1;
					}
					return GetActiveSceneId();
				}
				catch (MissingMemberException ex)
				{
					XuaLogger.AutoTranslator.Error((Exception)ex, "A 'missing member' error occurred while retriving translation scope. Disabling translation scopes.");
					Settings.EnableTranslationScoping = false;
				}
			}
			return -1;
		}

		private static int GetScopeFromComponent(Component component)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Scene scene = component.gameObject.scene;
			return ((Scene)(ref scene)).buildIndex;
		}

		public static int GetActiveSceneId()
		{
			if (UnityFeatures.SupportsSceneManager)
			{
				return GetActiveSceneIdBySceneManager();
			}
			return GetActiveSceneIdByApplication();
		}

		private static int GetActiveSceneIdBySceneManager()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).buildIndex;
		}

		public static void RegisterSceneLoadCallback(Action<int> sceneLoaded)
		{
			SceneManagerLoader.EnableSceneLoadScanInternal(sceneLoaded);
		}

		private static int GetActiveSceneIdByApplication()
		{
			return Application.loadedLevel;
		}
	}
	internal static class SceneManagerLoader
	{
		public static void EnableSceneLoadScanInternal(Action<int> sceneLoaded)
		{
			SceneManager.sceneLoaded += delegate(Scene arg1, LoadSceneMode arg2)
			{
				sceneLoaded(((Scene)(ref arg1)).buildIndex);
			};
		}
	}
	internal static class TranslationScopes
	{
		public const int None = -1;
	}
}
namespace XUnity.AutoTranslator.Plugin.Core
{
	public class AutoTranslationPlugin : MonoBehaviour, IMonoBehaviour, IMonoBehaviour_Update, IInternalTranslator, ITranslator, ITranslationRegistry
	{
		internal static AutoTranslationPlugin Current;

		private bool _hasResizedCurrentComponentDuringDiscovery;

		internal XuaWindow MainWindow;

		internal TranslationAggregatorWindow TranslationAggregatorWindow;

		internal TranslationAggregatorOptionsWindow TranslationAggregatorOptionsWindow;

		internal TranslationManager TranslationManager;

		internal TextTranslationCache TextCache;

		internal Dictionary<string, TextTranslationCache> PluginTextCaches = new Dictionary<string, TextTranslationCache>(StringComparer.OrdinalIgnoreCase);

		internal TextureTranslationCache TextureCache;

		internal UIResizeCache ResizeCache;

		internal SpamChecker SpamChecker;

		private Dictionary<string, UntranslatedText> CachedKeys = new Dictionary<string, UntranslatedText>(StringComparer.Ordinal);

		private List<Action<ComponentTranslationContext>> _shouldIgnore = new List<Action<ComponentTranslationContext>>();

		private List<string> _textsToCopyToClipboardOrdered = new List<string>();

		private HashSet<string> _textsToCopyToClipboard = new HashSet<string>();

		private float _clipboardUpdated;

		private HashSet<string> _immediatelyTranslating = new HashSet<string>();

		private bool _isInTranslatedMode = true;

		private bool _textHooksEnabled = true;

		private float _batchOperationSecondCounter;

		private bool _hasValidOverrideFont;

		private bool _hasOverridenFont;

		private bool _initialized;

		private bool _started;

		private bool _temporarilyDisabled;

		private string _requireSpriteRendererCheckCausedBy;

		private int _lastSpriteUpdateFrame = -1;

		private bool _isCalledFromSceneManager;

		private bool _translationReloadRequest;

		private bool _hasUiBeenSetup;

		private static bool _inputSupported;

		public void Initialize()
		{
			Current = this;
			Paths.Initialize();
			HarmonyLoader.Load();
			Settings.Configure();
			DebugConsole.Enable();
			InitializeHarmonyDetourBridge();
			InitializeTextTranslationCaches();
			HooksSetup.InstallTextHooks();
			HooksSetup.InstallImageHooks();
			HooksSetup.InstallSpriteRendererHooks();
			HooksSetup.InstallTextGetterCompatHooks();
			HooksSetup.InstallComponentBasedPluginTranslationHooks();
			TextureCache = new TextureTranslationCache();
			TextureCache.TextureTranslationFileChanged += TextureCache_TextureTranslationFileChanged;
			ResizeCache = new UIResizeCache();
			TranslationManager = new TranslationManager();
			TranslationManager.JobCompleted += OnJobCompleted;
			TranslationManager.JobFailed += OnJobFailed;
			TranslationManager.InitializeEndpoints();
			SpamChecker = new SpamChecker(TranslationManager);
			UnityTextParsers.Initialize();
			InitializeResourceRedirector();
			ValidateConfiguration();
			EnableSceneLoadScan();
			LoadFallbackFont();
			LoadTranslations(reload: false);
			XuaLogger.AutoTranslator.Info("Loaded XUnity.AutoTranslator into Unity [" + Application.unityVersion + "] game.");
		}

		private static void LoadFallbackFont()
		{
			try
			{
				if (!string.IsNullOrEmpty(Settings.FallbackFontTextMeshPro))
				{
					Object orCreateFallbackFontTextMeshPro = FontCache.GetOrCreateFallbackFontTextMeshPro();
					if (TMP_Settings_Properties.FallbackFontAssets == null)
					{
						XuaLogger.AutoTranslator.Info("Cannot use fallback font because it is not supported in this version.");
						return;
					}
					if (orCreateFallbackFontTextMeshPro == (Object)null)
					{
						XuaLogger.AutoTranslator.Warn("Could not load fallback font for TextMesh Pro: " + Settings.FallbackFontTextMeshPro);
						return;
					}
					((IList)TMP_Settings_Properties.FallbackFontAssets.Get((object)null)).Add(orCreateFallbackFontTextMeshPro);
					XuaLogger.AutoTranslator.Info("Loaded fallback font for TextMesh Pro: " + Settings.FallbackFontTextMeshPro);
				}
			}
			catch (Exception ex)
			{
				XuaLogger.AutoTranslator.Error(ex, "An error occurred while trying to load fallback font for TextMesh Pro.");
			}
		}

		private static void InitializeHarmonyDetourBridge()
		{
			try
			{
				if (Settings.InitializeHarmonyDetourBridge)
				{
					InitializeHarmonyDetourBridgeSafe();
				}
			}
			catch (Exception ex)
			{
				XuaLogger.AutoTranslator.Error(ex, "An error occurred while initializing harmony detour bridge.");
			}
		}

		private static void InitializeHarmonyDetourBridgeSafe()
		{
			HarmonyDetourBridge.Init(true, (Type)0);
		}

		private void InitializeTextTranslationCaches()
		{
			try
			{
				TextCache = new TextTranslationCache();
				TextCache.TextTranslationFileChanged += TextCache_TextTranslationFileChanged;
				DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Settings.TranslationsPath, "plugins"));
				if (directoryInfo.Exists)
				{
					DirectoryInfo[] directories = directoryInfo.GetDirectories();
					foreach (DirectoryInfo directoryInfo2 in directories)
					{
						TextTranslationCache value = new TextTranslationCache(directoryInfo2);
						PluginTextCaches.Add(directoryInfo2.Name, value);
					}
				}
			}
			catch (Exception ex)
			{
				XuaLogger.AutoTranslator.Error(ex, "An error occurred while initializing text translation caches.");
			}
		}

		private void TextCache_TextTranslationFileChanged()
		{
			_translationReloadRequest = true;
		}

		private void TextureCache_TextureTranslationFileChanged()
		{
			_translationReloadRequest = true;
		}

		private static void EnableLogAllLoadedResources()
		{
			ResourceRedirection.LogAllLoadedResources = true;
		}

		private void EnableTextAssetLoadedHandler()
		{
			new TextAssetLoadedHandler();
		}

		private void InitializeResourceRedirector()
		{
			try
			{
				if (Settings.LogAllLoadedResources)
				{
					EnableLogAllLoadedResources();
				}
				if (Settings.EnableTextAssetRedirector)
				{
					EnableTextAssetLoadedHandler();
				}
			}
			catch (Exception ex)
			{
				XuaLogger.AutoTranslator.Error(ex, "An error occurred while initializing resource redirectors.");
			}
		}

		private void InitializeGUI()
		{
			Dis

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.AutoTranslator/XUnity.AutoTranslator.Plugin.ExtProtocol.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("gravydevsupreme")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Package that contains a simple inter-process protocol format used in XUnity.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("XUnity.AutoTranslator.Plugin.ExtProtocol")]
[assembly: AssemblyTitle("XUnity.AutoTranslator.Plugin.ExtProtocol")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace XUnity.AutoTranslator.Plugin.ExtProtocol;

public class ConfigurationMessage : ProtocolMessage
{
	public static readonly string Type = "4";

	public string Config { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		Config = reader.ReadToEnd();
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.Write(Config);
	}
}
public static class ExtProtocolConvert
{
	private static readonly Dictionary<string, Type> IdToType;

	private static readonly Dictionary<Type, string> TypeToId;

	static ExtProtocolConvert()
	{
		IdToType = new Dictionary<string, Type>();
		TypeToId = new Dictionary<Type, string>();
		Register(TranslationRequest.Type, typeof(TranslationRequest));
		Register(TranslationResponse.Type, typeof(TranslationResponse));
		Register(TranslationError.Type, typeof(TranslationError));
		Register(ConfigurationMessage.Type, typeof(ConfigurationMessage));
	}

	public static void Register(string id, Type type)
	{
		IdToType[id] = type;
		TypeToId[type] = id;
	}

	public static string Encode(ProtocolMessage message)
	{
		StringWriter stringWriter = new StringWriter();
		string value = TypeToId[message.GetType()];
		stringWriter.WriteLine(value);
		message.Encode(stringWriter);
		return Convert.ToBase64String(Encoding.UTF8.GetBytes(stringWriter.ToString()), Base64FormattingOptions.None);
	}

	public static ProtocolMessage Decode(string message)
	{
		StringReader stringReader = new StringReader(Encoding.UTF8.GetString(Convert.FromBase64String(message)));
		string key = stringReader.ReadLine();
		ProtocolMessage obj = (ProtocolMessage)Activator.CreateInstance(IdToType[key]);
		obj.Decode(stringReader);
		return obj;
	}
}
public abstract class ProtocolMessage
{
	public Guid Id { get; set; }

	internal abstract void Decode(TextReader reader);

	internal abstract void Encode(TextWriter writer);
}
public enum StatusCode
{
	OK = 0,
	Blocked = 1,
	Unknown = 1000
}
public class TranslationError : ProtocolMessage
{
	public static readonly string Type = "3";

	public string Reason { get; set; }

	public StatusCode FailureCode { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		FailureCode = (StatusCode)int.Parse(reader.ReadLine());
		Reason = reader.ReadToEnd();
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine((int)FailureCode);
		writer.Write(Reason);
	}
}
public class TranslationRequest : ProtocolMessage
{
	public static readonly string Type = "1";

	private string[] _untranslatedTexts;

	public string SourceLanguage { get; set; }

	public string DestinationLanguage { get; set; }

	public string[] UntranslatedTexts => _untranslatedTexts ?? (_untranslatedTexts = UntranslatedTextInfos.Select((TransmittableUntranslatedTextInfo x) => x.UntranslatedText).ToArray());

	public TransmittableUntranslatedTextInfo[] UntranslatedTextInfos { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		SourceLanguage = reader.ReadLine();
		DestinationLanguage = reader.ReadLine();
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		TransmittableUntranslatedTextInfo[] array = new TransmittableUntranslatedTextInfo[num];
		for (int i = 0; i < num; i++)
		{
			TransmittableUntranslatedTextInfo transmittableUntranslatedTextInfo = new TransmittableUntranslatedTextInfo();
			transmittableUntranslatedTextInfo.Decode(reader);
			array[i] = transmittableUntranslatedTextInfo;
		}
		UntranslatedTextInfos = array;
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine(SourceLanguage);
		writer.WriteLine(DestinationLanguage);
		writer.WriteLine(UntranslatedTextInfos.Length.ToString(CultureInfo.InvariantCulture));
		TransmittableUntranslatedTextInfo[] untranslatedTextInfos = UntranslatedTextInfos;
		for (int i = 0; i < untranslatedTextInfos.Length; i++)
		{
			untranslatedTextInfos[i].Encode(writer);
		}
	}
}
public class TranslationResponse : ProtocolMessage
{
	public static readonly string Type = "2";

	public string[] TranslatedTexts { get; set; }

	internal override void Decode(TextReader reader)
	{
		base.Id = new Guid(reader.ReadLine());
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array = new string[num];
		for (int i = 0; i < num; i++)
		{
			string s = reader.ReadLine();
			string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s));
			array[i] = @string;
		}
		TranslatedTexts = array;
	}

	internal override void Encode(TextWriter writer)
	{
		writer.WriteLine(base.Id.ToString());
		writer.WriteLine(TranslatedTexts.Length.ToString(CultureInfo.InvariantCulture));
		string[] translatedTexts = TranslatedTexts;
		foreach (string s in translatedTexts)
		{
			string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None);
			writer.WriteLine(value);
		}
	}
}
public class TransmittableUntranslatedTextInfo
{
	public string[] ContextBefore { get; set; }

	public string UntranslatedText { get; set; }

	public string[] ContextAfter { get; set; }

	public TransmittableUntranslatedTextInfo(string[] contextBefore, string untranslatedText, string[] contextAfter)
	{
		ContextBefore = contextBefore;
		UntranslatedText = untranslatedText;
		ContextAfter = contextAfter;
	}

	public TransmittableUntranslatedTextInfo()
	{
	}

	internal void Encode(TextWriter writer)
	{
		string[] contextBefore = ContextBefore;
		writer.WriteLine(((contextBefore != null) ? contextBefore.Length : 0).ToString(CultureInfo.InvariantCulture));
		if (ContextBefore != null)
		{
			string[] contextBefore2 = ContextBefore;
			foreach (string s in contextBefore2)
			{
				string value = Convert.ToBase64String(Encoding.UTF8.GetBytes(s), Base64FormattingOptions.None);
				writer.WriteLine(value);
			}
		}
		string[] contextAfter = ContextAfter;
		writer.WriteLine(((contextAfter != null) ? contextAfter.Length : 0).ToString(CultureInfo.InvariantCulture));
		if (ContextAfter != null)
		{
			string[] contextBefore2 = ContextAfter;
			foreach (string s2 in contextBefore2)
			{
				string value2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(s2), Base64FormattingOptions.None);
				writer.WriteLine(value2);
			}
		}
		string value3 = Convert.ToBase64String(Encoding.UTF8.GetBytes(UntranslatedText), Base64FormattingOptions.None);
		writer.WriteLine(value3);
	}

	internal void Decode(TextReader reader)
	{
		int num = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array = new string[num];
		for (int i = 0; i < num; i++)
		{
			string s = reader.ReadLine();
			string @string = Encoding.UTF8.GetString(Convert.FromBase64String(s));
			array[i] = @string;
		}
		ContextBefore = array;
		int num2 = int.Parse(reader.ReadLine(), CultureInfo.InvariantCulture);
		string[] array2 = new string[num2];
		for (int j = 0; j < num2; j++)
		{
			string s2 = reader.ReadLine();
			string string2 = Encoding.UTF8.GetString(Convert.FromBase64String(s2));
			array2[j] = string2;
		}
		ContextAfter = array2;
		string s3 = reader.ReadLine();
		string string3 = Encoding.UTF8.GetString(Convert.FromBase64String(s3));
		UntranslatedText = string3;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.BepIn-5x.dll

Decompiled 10 months ago
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("XUnity.ResourceRedirector.BepIn-5x")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("XUnity.ResourceRedirector.BepIn-5x")]
[assembly: AssemblyTitle("XUnity.ResourceRedirector.BepIn-5x")]
[assembly: AssemblyVersion("1.1.1.0")]
namespace XUnity.ResourceRedirector.BepIn_5x;

[BepInPlugin("gravydevsupreme.xunity.resourceredirector", "XUnity Resource Redirector", "1.1.1")]
public class ResourceRedirectorPlugin : BaseUnityPlugin
{
	[Category("Settings")]
	[DisplayName("Log all loaded resources")]
	[Description("Indicates whether or not all loaded resources should be logged to the console. Prepare for spam if enabled.")]
	public ConfigWrapper<bool> LogAllLoadedResources { get; set; }

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		LogAllLoadedResources = ((BaseUnityPlugin)this).Config.Wrap<bool>(new ConfigDefinition("General", "LogAllLoadedResources", (string)null), false);
		ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
		LogAllLoadedResources.SettingChanged += delegate
		{
			ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
		};
		((BaseUnityPlugin)this).Config.ConfigReloaded += Config_ConfigReloaded;
	}

	private void Config_ConfigReloaded(object sender, EventArgs e)
	{
		ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.BepInEx-IL2CPP.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using Microsoft.CodeAnalysis;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace XUnity.ResourceRedirector.BepInEx
{
	[BepInPlugin("gravydevsupreme.xunity.resourceredirector", "XUnity Resource Redirector", "2.1.0")]
	public class ResourceRedirectorPlugin : BasePlugin
	{
		public static ConfigEntry<bool> LogAllLoadedResources { get; set; }

		public static ConfigEntry<bool> LogCallbackOrder { get; set; }

		public override void Load()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			LogAllLoadedResources = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log all loaded resources"), false, (ConfigDescription)null);
			ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
			LogAllLoadedResources.SettingChanged += delegate
			{
				ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
			};
			LogCallbackOrder = ((BasePlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log callback order"), false, (ConfigDescription)null);
			ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
			LogCallbackOrder.SettingChanged += delegate
			{
				ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
			};
			((BasePlugin)this).Config.ConfigReloaded += Config_ConfigReloaded;
		}

		private static void Config_ConfigReloaded(object sender, EventArgs e)
		{
			ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
			ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
		}
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.BepInEx.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("XUnity.ResourceRedirector.BepInEx")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0")]
[assembly: AssemblyProduct("XUnity.ResourceRedirector.BepInEx")]
[assembly: AssemblyTitle("XUnity.ResourceRedirector.BepInEx")]
[assembly: AssemblyVersion("2.1.0.0")]
namespace XUnity.ResourceRedirector.BepInEx;

[BepInPlugin("gravydevsupreme.xunity.resourceredirector", "XUnity Resource Redirector", "2.1.0")]
public class ResourceRedirectorPlugin : BaseUnityPlugin
{
	public static ConfigEntry<bool> LogAllLoadedResources { get; set; }

	public static ConfigEntry<bool> LogCallbackOrder { get; set; }

	private void Awake()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		LogAllLoadedResources = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log all loaded resources"), false, (ConfigDescription)null);
		ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
		LogAllLoadedResources.SettingChanged += delegate
		{
			ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
		};
		LogCallbackOrder = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("Diagnostics", "Log callback order"), false, (ConfigDescription)null);
		ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
		LogCallbackOrder.SettingChanged += delegate
		{
			ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
		};
		((BaseUnityPlugin)this).Config.ConfigReloaded += Config_ConfigReloaded;
	}

	private static void Config_ConfigReloaded(object sender, EventArgs e)
	{
		ResourceRedirection.LogAllLoadedResources = LogAllLoadedResources.Value;
		ResourceRedirection.LogCallbackOrder = LogCallbackOrder.Value;
	}
}

mods/ttk-Brazilian_Portuguese_Localization-1.1.3/BepInEx/plugins/XUnity.ResourceRedirector/XUnity.ResourceRedirector.dll

Decompiled 10 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
using UnityEngine;
using XUnity.Common.Constants;
using XUnity.Common.Extensions;
using XUnity.Common.Harmony;
using XUnity.Common.Logging;
using XUnity.Common.MonoMod;
using XUnity.Common.Utilities;
using XUnity.ResourceRedirector.Constants;
using XUnity.ResourceRedirector.Hooks;
using XUnity.ResourceRedirector.Properties;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("gravydevsupreme")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Main development dependency for XUnity Resource Redirector.")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0")]
[assembly: AssemblyProduct("XUnity.ResourceRedirector")]
[assembly: AssemblyTitle("XUnity.ResourceRedirector")]
[assembly: AssemblyVersion("2.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace XUnity.ResourceRedirector
{
	internal class AssetBundleExtensionData
	{
		private string _normalizedPath;

		private string _path;

		public string NormalizedPath
		{
			get
			{
				if (Path != null && _normalizedPath == null)
				{
					_normalizedPath = StringExtensions.MakeRelativePath(Path.ToLowerInvariant(), EnvironmentEx.LoweredCurrentDirectory);
				}
				return _normalizedPath;
			}
		}

		public string Path
		{
			get
			{
				return _path;
			}
			set
			{
				if (_path != value)
				{
					_path = value;
					_normalizedPath = null;
				}
			}
		}
	}
	public static class AssetBundleHelper
	{
		internal static string PathForLoadedInMemoryBundle;

		public static AssetBundle CreateEmptyAssetBundle()
		{
			byte[] empty = Resources.empty;
			CabHelper.RandomizeCab(empty);
			return AssetBundle.LoadFromMemory(empty);
		}

		public static AssetBundleCreateRequest CreateEmptyAssetBundleRequest()
		{
			byte[] empty = Resources.empty;
			CabHelper.RandomizeCab(empty);
			return AssetBundle.LoadFromMemoryAsync(empty);
		}

		public static AssetBundle LoadFromMemory(string path, byte[] binary, uint crc)
		{
			try
			{
				PathForLoadedInMemoryBundle = path;
				return AssetBundle.LoadFromMemory(binary, crc);
			}
			finally
			{
				PathForLoadedInMemoryBundle = null;
			}
		}

		public static AssetBundleCreateRequest LoadFromMemoryAsync(string path, byte[] binary, uint crc)
		{
			try
			{
				PathForLoadedInMemoryBundle = path;
				return AssetBundle.LoadFromMemoryAsync(binary, crc);
			}
			finally
			{
				PathForLoadedInMemoryBundle = null;
			}
		}

		public static AssetBundle LoadFromFileWithRandomizedCabIfRequired(string path, uint crc, ulong offset)
		{
			return LoadFromFileWithRandomizedCabIfRequired(path, crc, offset, confirmFileExists: true);
		}

		internal static AssetBundle LoadFromFileWithRandomizedCabIfRequired(string path, uint crc, ulong offset, bool confirmFileExists)
		{
			AssetBundle val = AssetBundle.LoadFromFile(path, crc, offset);
			if ((Object)(object)val == (Object)null && (!confirmFileExists || File.Exists(path)))
			{
				byte[] array;
				using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
				{
					long num = fileStream.Length - (long)offset;
					fileStream.Seek((long)offset, SeekOrigin.Begin);
					array = StreamExtensions.ReadFully((Stream)fileStream, (int)num);
				}
				CabHelper.RandomizeCabWithAnyLength(array);
				XuaLogger.ResourceRedirector.Warn("Randomized CAB for '" + path + "' in order to load it because another asset bundle already uses its CAB-string. You can ignore the previous error message, but this is likely caused by two mods incorrectly using the same CAB-string.");
				return AssetBundle.LoadFromMemory(array);
			}
			return val;
		}
	}
	public class AssetBundleLoadedContext
	{
		private string _normalizedPath;

		public AssetBundleLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; set; }

		internal bool SkipRemainingPostfixes { get; private set; }

		internal AssetBundleLoadedContext(AssetBundleLoadingParameters parameters, AssetBundle bundle)
		{
			Parameters = parameters;
			Bundle = bundle;
		}

		public string GetNormalizedPath()
		{
			if (_normalizedPath == null && Parameters.Path != null)
			{
				_normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory);
			}
			return _normalizedPath;
		}

		public void Complete(bool skipRemainingPostfixes = true)
		{
			SkipRemainingPostfixes = skipRemainingPostfixes;
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public class AssetBundleLoadingContext : IAssetBundleLoadingContext
	{
		private string _normalizedPath;

		public AssetBundleLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; set; }

		internal bool SkipRemainingPrefixes { get; private set; }

		internal bool SkipOriginalCall { get; private set; }

		internal bool SkipAllPostfixes { get; private set; }

		internal AssetBundleLoadingContext(AssetBundleLoadingParameters parameters)
		{
			Parameters = parameters;
		}

		public string GetNormalizedPath()
		{
			if (_normalizedPath == null && Parameters.Path != null)
			{
				_normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory);
			}
			return _normalizedPath;
		}

		public void Complete()
		{
			Complete(skipRemainingPrefixes: true, true, true);
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true)
		{
			Complete(skipRemainingPrefixes, skipOriginalCall, true);
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true)
		{
			SkipRemainingPrefixes = skipRemainingPrefixes;
			if (skipOriginalCall.HasValue)
			{
				SkipOriginalCall = skipOriginalCall.Value;
			}
			if (skipAllPostfixes.HasValue)
			{
				SkipAllPostfixes = skipAllPostfixes.Value;
			}
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public class AssetBundleLoadingParameters
	{
		public string Path { get; set; }

		public uint Crc { get; set; }

		public ulong Offset { get; set; }

		public Stream Stream { get; set; }

		public uint ManagedReadBufferSize { get; }

		public byte[] Binary { get; set; }

		public AssetBundleLoadType LoadType { get; }

		internal AssetBundleLoadingParameters(byte[] data, string path, uint crc, ulong offset, Stream stream, uint managedReadBufferSize, AssetBundleLoadType loadType)
		{
			Binary = data;
			Path = path;
			Crc = crc;
			Offset = offset;
			Stream = stream;
			ManagedReadBufferSize = managedReadBufferSize;
			LoadType = loadType;
		}
	}
	public enum AssetBundleLoadType
	{
		LoadFromFile = 1,
		LoadFromMemory,
		LoadFromStream
	}
	public class AssetLoadedContext : IAssetOrResourceLoadedContext
	{
		private AssetBundleExtensionData _ext;

		private bool _lookedForExt;

		private BackingFieldOrArray _backingField;

		public AssetLoadedParameters Parameters { get; }

		public AssetBundle Bundle { get; }

		public Object[] Assets
		{
			get
			{
				return _backingField.Array;
			}
			set
			{
				_backingField.Array = value;
			}
		}

		public Object Asset
		{
			get
			{
				return _backingField.Field;
			}
			set
			{
				_backingField.Field = value;
			}
		}

		internal bool SkipRemainingPostfixes { get; private set; }

		internal AssetLoadedContext(AssetLoadedParameters parameters, AssetBundle bundle, Object[] assets)
		{
			Parameters = parameters;
			Bundle = bundle;
			_backingField = new BackingFieldOrArray(assets);
		}

		internal AssetLoadedContext(AssetLoadedParameters parameters, AssetBundle bundle, Object asset)
		{
			Parameters = parameters;
			Bundle = bundle;
			_backingField = new BackingFieldOrArray(asset);
		}

		public bool HasReferenceBeenRedirectedBefore(Object asset)
		{
			return ExtensionDataHelper.GetExtensionData<ResourceExtensionData>((object)asset)?.HasBeenRedirected ?? false;
		}

		public string GetUniqueFileSystemAssetPath(Object asset)
		{
			ResourceExtensionData orCreateExtensionData = ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)asset);
			if (orCreateExtensionData.FullFileSystemAssetPath == null)
			{
				string text = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle)?.NormalizedPath;
				string path = (string.IsNullOrEmpty(text) ? "unnamed_assetbundle" : text.ToLowerInvariant());
				string name = asset.name;
				if (!string.IsNullOrEmpty(name))
				{
					path = Path.Combine(path, name.ToLowerInvariant());
				}
				else
				{
					string text2 = null;
					if (Assets.Length > 1)
					{
						int num = Array.IndexOf(Assets, asset);
						text2 = ((num != -1) ? ("_" + num.ToString(CultureInfo.InvariantCulture)) : "_with_unknown_index");
					}
					path = Path.Combine(path, (Parameters.LoadType == AssetLoadType.LoadMainAsset) ? "main_asset" : ("unnamed_asset" + text2));
				}
				path = StringExtensions.UseCorrectDirectorySeparators(path);
				orCreateExtensionData.FullFileSystemAssetPath = path;
			}
			return orCreateExtensionData.FullFileSystemAssetPath;
		}

		public string GetAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.Path;
		}

		public string GetNormalizedAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.NormalizedPath;
		}

		public void Complete(bool skipRemainingPostfixes = true)
		{
			SkipRemainingPostfixes = skipRemainingPostfixes;
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public class AssetLoadedParameters
	{
		public string Name { get; }

		public Type Type { get; }

		public AssetLoadType LoadType { get; }

		internal AssetLoadedParameters(string name, Type type, AssetLoadType loadType)
		{
			Name = name;
			Type = type;
			LoadType = loadType;
		}
	}
	public class AssetLoadingContext : IAssetLoadingContext
	{
		private AssetBundleExtensionData _ext;

		private bool _lookedForExt;

		private BackingFieldOrArray _backingField;

		public AssetLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; }

		public Object[] Assets
		{
			get
			{
				return _backingField.Array;
			}
			set
			{
				_backingField.Array = value;
			}
		}

		public Object Asset
		{
			get
			{
				return _backingField.Field;
			}
			set
			{
				_backingField.Field = value;
			}
		}

		internal bool SkipRemainingPrefixes { get; private set; }

		internal bool SkipOriginalCall { get; private set; }

		internal bool SkipAllPostfixes { get; private set; }

		internal AssetLoadingContext(AssetLoadingParameters parameters, AssetBundle bundle)
		{
			Parameters = parameters;
			Bundle = bundle;
		}

		public string GetAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.Path;
		}

		public string GetNormalizedAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.NormalizedPath;
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true)
		{
			SkipRemainingPrefixes = skipRemainingPrefixes;
			if (skipOriginalCall.HasValue)
			{
				SkipOriginalCall = skipOriginalCall.Value;
			}
			if (skipAllPostfixes.HasValue)
			{
				SkipAllPostfixes = skipAllPostfixes.Value;
			}
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public class AssetLoadingParameters
	{
		public string Name { get; set; }

		public Type Type { get; set; }

		public AssetLoadType LoadType { get; }

		internal AssetLoadingParameters(string name, Type type, AssetLoadType loadType)
		{
			Name = name;
			Type = type;
			LoadType = loadType;
		}

		internal AssetLoadedParameters ToAssetLoadedParameters()
		{
			return new AssetLoadedParameters(Name, Type, LoadType);
		}
	}
	public enum AssetLoadType
	{
		LoadMainAsset = 1,
		LoadByType,
		LoadNamed,
		LoadNamedWithSubAssets
	}
	internal class AsyncAssetBundleLoadInfo
	{
		public AssetBundleLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; }

		public bool SkipAllPostfixes { get; }

		public AsyncAssetBundleLoadingResolve ResolveType { get; }

		public AsyncAssetBundleLoadInfo(AssetBundleLoadingParameters parameters, AssetBundle bundle, bool skipAllPostfixes, AsyncAssetBundleLoadingResolve resolveType)
		{
			Parameters = parameters;
			Bundle = bundle;
			SkipAllPostfixes = skipAllPostfixes;
			ResolveType = resolveType;
		}
	}
	public class AsyncAssetBundleLoadingContext : IAssetBundleLoadingContext
	{
		private string _normalizedPath;

		private AssetBundle _bundle;

		private AssetBundleCreateRequest _request;

		public AssetBundleLoadingParameters Parameters { get; }

		public AssetBundleCreateRequest Request
		{
			get
			{
				return _request;
			}
			set
			{
				_request = value;
				ResolveType = AsyncAssetBundleLoadingResolve.ThroughRequest;
			}
		}

		public AssetBundle Bundle
		{
			get
			{
				return _bundle;
			}
			set
			{
				if (!ResourceRedirection.SyncOverAsyncEnabled)
				{
					throw new InvalidOperationException("Trying to set the Bundle property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'.");
				}
				_bundle = value;
				ResolveType = AsyncAssetBundleLoadingResolve.ThroughBundle;
			}
		}

		public AsyncAssetBundleLoadingResolve ResolveType { get; set; }

		internal bool SkipRemainingPrefixes { get; private set; }

		internal bool SkipOriginalCall { get; set; }

		internal bool SkipAllPostfixes { get; private set; }

		internal AsyncAssetBundleLoadingContext(AssetBundleLoadingParameters parameters)
		{
			Parameters = parameters;
		}

		public string GetNormalizedPath()
		{
			if (_normalizedPath == null && Parameters.Path != null)
			{
				_normalizedPath = StringExtensions.MakeRelativePath(StringExtensions.UseCorrectDirectorySeparators(Parameters.Path.ToLowerInvariant()), EnvironmentEx.LoweredCurrentDirectory);
			}
			return _normalizedPath;
		}

		public void Complete()
		{
			Complete(skipRemainingPrefixes: true, true, true);
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true)
		{
			Complete(skipRemainingPrefixes, skipOriginalCall, true);
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true)
		{
			SkipRemainingPrefixes = skipRemainingPrefixes;
			if (skipOriginalCall.HasValue)
			{
				SkipOriginalCall = skipOriginalCall.Value;
			}
			if (skipAllPostfixes.HasValue)
			{
				SkipAllPostfixes = skipAllPostfixes.Value;
			}
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public enum AsyncAssetBundleLoadingResolve
	{
		ThroughRequest,
		ThroughBundle
	}
	internal class AsyncAssetLoadInfo
	{
		public AssetLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; }

		public bool SkipAllPostfixes { get; }

		public AsyncAssetLoadingResolve ResolveType { get; }

		public Object[] Assets { get; }

		public AsyncAssetLoadInfo(AssetLoadingParameters parameters, AssetBundle bundle, bool skipAllPostfixes, AsyncAssetLoadingResolve resolveType, Object[] assets)
		{
			Parameters = parameters;
			Bundle = bundle;
			SkipAllPostfixes = skipAllPostfixes;
			ResolveType = resolveType;
			Assets = assets;
		}
	}
	public class AsyncAssetLoadingContext : IAssetLoadingContext
	{
		private AssetBundleExtensionData _ext;

		private bool _lookedForExt;

		private Object[] _assets;

		private AssetBundleRequest _request;

		private BackingFieldOrArray _backingField;

		public AssetLoadingParameters Parameters { get; }

		public AssetBundle Bundle { get; }

		public AssetBundleRequest Request
		{
			get
			{
				return _request;
			}
			set
			{
				_request = value;
				ResolveType = AsyncAssetLoadingResolve.ThroughRequest;
			}
		}

		public Object[] Assets
		{
			get
			{
				return _backingField.Array;
			}
			set
			{
				if (!ResourceRedirection.SyncOverAsyncEnabled)
				{
					throw new InvalidOperationException("Trying to set the Assets/Asset property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'.");
				}
				_backingField.Array = value;
				ResolveType = AsyncAssetLoadingResolve.ThroughAssets;
			}
		}

		public Object Asset
		{
			get
			{
				return _backingField.Field;
			}
			set
			{
				if (!ResourceRedirection.SyncOverAsyncEnabled)
				{
					throw new InvalidOperationException("Trying to set the Assets/Asset property in async load operation while 'SyncOverAsyncAssetLoads' is disabled is not allowed. Consider settting the Request property instead if possible or enabling 'SyncOverAsyncAssetLoads' through the method 'ResourceRedirection.EnableSyncOverAsyncAssetLoads()'.");
				}
				_backingField.Field = value;
				ResolveType = AsyncAssetLoadingResolve.ThroughAssets;
			}
		}

		public AsyncAssetLoadingResolve ResolveType { get; set; }

		internal bool SkipRemainingPrefixes { get; private set; }

		internal bool SkipOriginalCall { get; set; }

		internal bool SkipAllPostfixes { get; private set; }

		internal AsyncAssetLoadingContext(AssetLoadingParameters parameters, AssetBundle bundle)
		{
			Parameters = parameters;
			Bundle = bundle;
		}

		public string GetAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.Path;
		}

		public string GetNormalizedAssetBundlePath()
		{
			if (!_lookedForExt)
			{
				_lookedForExt = true;
				_ext = ExtensionDataHelper.GetExtensionData<AssetBundleExtensionData>((object)Bundle);
			}
			return _ext?.NormalizedPath;
		}

		public void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true)
		{
			SkipRemainingPrefixes = skipRemainingPrefixes;
			if (skipOriginalCall.HasValue)
			{
				SkipOriginalCall = skipOriginalCall.Value;
			}
			if (skipAllPostfixes.HasValue)
			{
				SkipAllPostfixes = skipAllPostfixes.Value;
			}
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public enum AsyncAssetLoadingResolve
	{
		ThroughRequest,
		ThroughAssets
	}
	internal struct BackingFieldOrArray
	{
		private Object _field;

		private Object[] _array;

		private BackingSource _source;

		public Object Field
		{
			get
			{
				if (_source == BackingSource.None)
				{
					return null;
				}
				if (_source == BackingSource.SingleField)
				{
					return _field;
				}
				if (_array == null || _array.Length == 0)
				{
					return null;
				}
				return _array[0];
			}
			set
			{
				_field = value;
				_array = null;
				_source = BackingSource.SingleField;
			}
		}

		public Object[] Array
		{
			get
			{
				if (_source == BackingSource.Array)
				{
					return _array;
				}
				if (_field == (Object)null)
				{
					Array = (Object[])(object)new Object[0];
				}
				else
				{
					Array = (Object[])(object)new Object[1] { _field };
				}
				return _array;
			}
			set
			{
				_field = null;
				_array = value;
				_source = BackingSource.Array;
			}
		}

		public BackingFieldOrArray(Object field)
		{
			_field = field;
			_array = null;
			_source = BackingSource.SingleField;
		}

		public BackingFieldOrArray(Object[] array)
		{
			_field = null;
			_array = array;
			_source = BackingSource.Array;
		}

		public IEnumerable<Object> IterateObjects()
		{
			if (_array != null)
			{
				Object[] array = _array;
				for (int i = 0; i < array.Length; i++)
				{
					yield return array[i];
				}
			}
			else if (_field != (Object)null)
			{
				yield return _field;
			}
		}
	}
	internal enum BackingSource : byte
	{
		None,
		SingleField,
		Array
	}
	public static class CallbackPriority
	{
		public const int Default = 0;
	}
	public enum HookBehaviour
	{
		OneCallbackPerLoadCall = 1,
		OneCallbackPerResourceLoaded
	}
	public interface IAssetBundleLoadingContext
	{
		AssetBundleLoadingParameters Parameters { get; }

		AssetBundle Bundle { get; set; }

		string GetNormalizedPath();

		void Complete();

		void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true);

		void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true);

		void DisableRecursion();
	}
	public interface IAssetLoadingContext
	{
		AssetLoadingParameters Parameters { get; }

		AssetBundle Bundle { get; }

		Object[] Assets { get; set; }

		Object Asset { get; set; }

		string GetAssetBundlePath();

		string GetNormalizedAssetBundlePath();

		void Complete(bool skipRemainingPrefixes = true, bool? skipOriginalCall = true, bool? skipAllPostfixes = true);

		void DisableRecursion();
	}
	public interface IAssetOrResourceLoadedContext
	{
		Object[] Assets { get; set; }

		Object Asset { get; set; }

		bool HasReferenceBeenRedirectedBefore(Object asset);

		string GetUniqueFileSystemAssetPath(Object asset);

		void Complete(bool skipRemainingPostfixes = true);

		void DisableRecursion();
	}
	internal class PrioritizedCallback
	{
		public static PrioritizedCallback<TCallback> Create<TCallback>(TCallback item, int priority) where TCallback : Delegate
		{
			return new PrioritizedCallback<TCallback>(item, priority);
		}
	}
	internal class PrioritizedCallback<TCallback> : PrioritizedCallback, IComparable<PrioritizedCallback<TCallback>>, IEquatable<PrioritizedCallback<TCallback>> where TCallback : Delegate
	{
		public TCallback Callback { get; }

		public int Priority { get; }

		public Type TargetType { get; set; }

		public bool IsBeingCalled { get; set; }

		public PrioritizedCallback(TCallback callback, int priority)
		{
			Callback = callback;
			Priority = priority;
			TargetType = callback.Target?.GetType();
		}

		public int CompareTo(PrioritizedCallback<TCallback> other)
		{
			return other.Priority.CompareTo(Priority);
		}

		public override bool Equals(object obj)
		{
			return Equals(obj as PrioritizedCallback<TCallback>);
		}

		public bool Equals(PrioritizedCallback<TCallback> other)
		{
			return EqualityComparer<TCallback>.Default.Equals(Callback, other.Callback);
		}

		public override int GetHashCode()
		{
			return -1406788065 * -1521134295 + EqualityComparer<TCallback>.Default.GetHashCode(Callback);
		}

		public override string ToString()
		{
			return "[" + Priority + "] " + (TargetType?.Name ?? Callback.Method.DeclaringType?.Name) + "." + Callback.Method?.Name;
		}
	}
	internal class ResourceExtensionData
	{
		public bool HasBeenRedirected { get; set; }

		public string FullFileSystemAssetPath { get; set; }
	}
	public class ResourceLoadedContext : IAssetOrResourceLoadedContext
	{
		private BackingFieldOrArray _backingField;

		public ResourceLoadedParameters Parameters { get; }

		public Object[] Assets
		{
			get
			{
				return _backingField.Array;
			}
			set
			{
				_backingField.Array = value;
			}
		}

		public Object Asset
		{
			get
			{
				return _backingField.Field;
			}
			set
			{
				_backingField.Field = value;
			}
		}

		internal bool SkipRemainingPostfixes { get; set; }

		internal ResourceLoadedContext(ResourceLoadedParameters parameters, Object[] assets)
		{
			Parameters = parameters;
			_backingField = new BackingFieldOrArray(assets);
		}

		internal ResourceLoadedContext(ResourceLoadedParameters parameters, Object asset)
		{
			Parameters = parameters;
			_backingField = new BackingFieldOrArray(asset);
		}

		public bool HasReferenceBeenRedirectedBefore(Object asset)
		{
			return ExtensionDataHelper.GetExtensionData<ResourceExtensionData>((object)asset)?.HasBeenRedirected ?? false;
		}

		public string GetUniqueFileSystemAssetPath(Object asset)
		{
			ResourceExtensionData orCreateExtensionData = ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)asset);
			if (orCreateExtensionData.FullFileSystemAssetPath == null)
			{
				string text = string.Empty;
				if (!string.IsNullOrEmpty(Parameters.Path))
				{
					text = Parameters.Path.ToLowerInvariant();
				}
				if (Parameters.LoadType == ResourceLoadType.LoadByType)
				{
					string name = asset.name;
					if (!string.IsNullOrEmpty(name))
					{
						text = Path.Combine(text, name.ToLowerInvariant());
					}
					else
					{
						string text2 = null;
						if (Assets.Length > 1)
						{
							int num = Array.IndexOf(Assets, asset);
							text2 = ((num != -1) ? ("_" + num.ToString(CultureInfo.InvariantCulture)) : "_with_unknown_index");
						}
						text = Path.Combine(text, "unnamed_asset" + text2);
					}
				}
				text = StringExtensions.UseCorrectDirectorySeparators(text);
				orCreateExtensionData.FullFileSystemAssetPath = text;
			}
			return orCreateExtensionData.FullFileSystemAssetPath;
		}

		public void Complete(bool skipRemainingPostfixes = true)
		{
			SkipRemainingPostfixes = skipRemainingPostfixes;
		}

		public void DisableRecursion()
		{
			ResourceRedirection.RecursionEnabled = false;
		}
	}
	public class ResourceLoadedParameters
	{
		public string Path { get; set; }

		public Type Type { get; set; }

		public ResourceLoadType LoadType { get; }

		internal ResourceLoadedParameters(string path, Type type, ResourceLoadType loadType)
		{
			Path = path;
			Type = type;
			LoadType = loadType;
		}
	}
	public enum ResourceLoadType
	{
		LoadByType = 1,
		LoadNamed,
		LoadNamedBuiltIn
	}
	public static class ResourceRedirection
	{
		private static readonly List<PrioritizedCallback<Action<AssetLoadedContext>>> PostfixRedirectionsForAssetsPerCall = new List<PrioritizedCallback<Action<AssetLoadedContext>>>();

		private static readonly List<PrioritizedCallback<Action<AssetLoadedContext>>> PostfixRedirectionsForAssetsPerResource = new List<PrioritizedCallback<Action<AssetLoadedContext>>>();

		private static readonly List<PrioritizedCallback<Action<ResourceLoadedContext>>> PostfixRedirectionsForResourcesPerCall = new List<PrioritizedCallback<Action<ResourceLoadedContext>>>();

		private static readonly List<PrioritizedCallback<Action<ResourceLoadedContext>>> PostfixRedirectionsForResourcesPerResource = new List<PrioritizedCallback<Action<ResourceLoadedContext>>>();

		private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAssetsPerCall = new List<PrioritizedCallback<Delegate>>();

		private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAsyncAssetsPerCall = new List<PrioritizedCallback<Delegate>>();

		private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAssetBundles = new List<PrioritizedCallback<Delegate>>();

		private static readonly List<PrioritizedCallback<Delegate>> PrefixRedirectionsForAsyncAssetBundles = new List<PrioritizedCallback<Delegate>>();

		private static readonly List<PrioritizedCallback<Action<AssetBundleLoadedContext>>> PostfixRedirectionsForAssetBundles = new List<PrioritizedCallback<Action<AssetBundleLoadedContext>>>();

		private static Action<AssetBundleLoadingContext> _emulateAssetBundles;

		private static Action<AsyncAssetBundleLoadingContext> _emulateAssetBundlesAsync;

		private static Action<AssetBundleLoadingContext> _redirectionMissingAssetBundlesToEmpty;

		private static Action<AsyncAssetBundleLoadingContext> _redirectionMissingAssetBundlesToEmptyAsync;

		private static bool _enabledRandomizeCabIfConflict = false;

		private static Action<AssetBundleLoadingContext> _enableCabRandomizationPrefix;

		private static Action<AsyncAssetBundleLoadingContext> _enableCabRandomizationPrefixAsync;

		private static Action<AssetBundleLoadedContext> _enableCabRandomizationPostfix;

		private static bool _initialized = false;

		private static bool _initializedSyncOverAsyncEnabled = false;

		private static bool _logAllLoadedResources = false;

		private static bool _isFiringAssetBundle;

		private static bool _isFiringResource;

		private static bool _isFiringAsset;

		private static bool _isRecursionDisabledPermanently;

		internal static bool RecursionEnabled = true;

		internal static bool SyncOverAsyncEnabled = false;

		public static bool LogAllLoadedResources
		{
			get
			{
				return _logAllLoadedResources;
			}
			set
			{
				if (value)
				{
					Initialize();
				}
				_logAllLoadedResources = value;
			}
		}

		public static bool LogCallbackOrder { get; set; }

		public static void Initialize()
		{
			if (!_initialized)
			{
				_initialized = true;
				HookingHelper.PatchAll((IEnumerable<Type>)ResourceAndAssetHooks.GeneralHooks, false);
			}
		}

		public static void EnableSyncOverAsyncAssetLoads()
		{
			Initialize();
			if (!_initializedSyncOverAsyncEnabled)
			{
				_initializedSyncOverAsyncEnabled = true;
				SyncOverAsyncEnabled = true;
				HookingHelper.PatchAll((IEnumerable<Type>)ResourceAndAssetHooks.SyncOverAsyncHooks, false);
			}
		}

		public static void DisableRecursionPermanently()
		{
			_isRecursionDisabledPermanently = true;
		}

		public static void EnableEmulateAssetBundles(int priority, string emulationDirectory)
		{
			if (_emulateAssetBundles == null && _emulateAssetBundlesAsync == null)
			{
				_emulateAssetBundles = delegate(AssetBundleLoadingContext ctx)
				{
					HandleAssetBundleEmulation<AssetBundleLoadingContext>(ctx, SetBundle);
				};
				_emulateAssetBundlesAsync = delegate(AsyncAssetBundleLoadingContext ctx)
				{
					HandleAssetBundleEmulation<AsyncAssetBundleLoadingContext>(ctx, SetRequest);
				};
				RegisterAssetBundleLoadingHook(priority, _emulateAssetBundles);
				RegisterAsyncAssetBundleLoadingHook(priority, _emulateAssetBundlesAsync);
			}
			void HandleAssetBundleEmulation<T>(T context, Action<T, string> changeBundle) where T : IAssetBundleLoadingContext
			{
				if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile)
				{
					string normalizedPath = context.GetNormalizedPath();
					string text = Path.Combine(emulationDirectory, normalizedPath);
					if (File.Exists(text))
					{
						changeBundle(context, text);
						ref T reference = ref context;
						T val = default(T);
						if (val == null)
						{
							val = reference;
							reference = ref val;
						}
						reference.Complete(skipRemainingPrefixes: true, true);
						XuaLogger.ResourceRedirector.Debug("Redirected asset bundle: '" + context.Parameters.Path + "' => '" + text + "'");
					}
				}
			}
			static void SetBundle(AssetBundleLoadingContext context, string path)
			{
				context.Bundle = AssetBundle.LoadFromFile(path, context.Parameters.Crc, context.Parameters.Offset);
			}
			static void SetRequest(AsyncAssetBundleLoadingContext context, string path)
			{
				context.Request = AssetBundle.LoadFromFileAsync(path, context.Parameters.Crc, context.Parameters.Offset);
			}
		}

		public static void DisableEmulateAssetBundles()
		{
			if (_emulateAssetBundles != null && _emulateAssetBundlesAsync != null)
			{
				UnregisterAssetBundleLoadingHook(_emulateAssetBundles);
				UnregisterAsyncAssetBundleLoadingHook(_emulateAssetBundlesAsync);
				_emulateAssetBundles = null;
				_emulateAssetBundlesAsync = null;
			}
		}

		public static void EnableRedirectMissingAssetBundlesToEmptyAssetBundle(int priority)
		{
			if (_redirectionMissingAssetBundlesToEmpty == null && _redirectionMissingAssetBundlesToEmptyAsync == null)
			{
				_redirectionMissingAssetBundlesToEmpty = delegate(AssetBundleLoadingContext ctx)
				{
					HandleMissingBundle<AssetBundleLoadingContext>(ctx, SetBundle);
				};
				_redirectionMissingAssetBundlesToEmptyAsync = delegate(AsyncAssetBundleLoadingContext ctx)
				{
					HandleMissingBundle<AsyncAssetBundleLoadingContext>(ctx, SetRequest);
				};
				RegisterAssetBundleLoadingHook(priority, _redirectionMissingAssetBundlesToEmpty);
				RegisterAsyncAssetBundleLoadingHook(priority, _redirectionMissingAssetBundlesToEmptyAsync);
			}
			static void HandleMissingBundle<TContext>(TContext context, Action<TContext, byte[]> changeBundle) where TContext : IAssetBundleLoadingContext
			{
				if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile && !File.Exists(context.Parameters.Path))
				{
					byte[] empty = Resources.empty;
					CabHelper.RandomizeCab(empty);
					changeBundle(context, empty);
					ref TContext reference = ref context;
					TContext val = default(TContext);
					if (val == null)
					{
						val = reference;
						reference = ref val;
					}
					reference.Complete(skipRemainingPrefixes: true, true);
					XuaLogger.ResourceRedirector.Warn("Tried to load non-existing asset bundle: " + context.Parameters.Path);
				}
			}
			static void SetBundle(AssetBundleLoadingContext context, byte[] assetBundleData)
			{
				AssetBundle bundle = AssetBundle.LoadFromMemory(assetBundleData);
				context.Bundle = bundle;
			}
			static void SetRequest(AsyncAssetBundleLoadingContext context, byte[] assetBundleData)
			{
				AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(assetBundleData);
				context.Request = request;
			}
		}

		public static void EnableRandomizeCabIfConflict(int priority, bool forceRandomizeWhenInMemory)
		{
			if (_enabledRandomizeCabIfConflict)
			{
				return;
			}
			_enabledRandomizeCabIfConflict = true;
			if (forceRandomizeWhenInMemory)
			{
				_enableCabRandomizationPrefix = delegate(AssetBundleLoadingContext ctx)
				{
					HandleCabRandomizePrefix(ctx);
				};
				_enableCabRandomizationPrefixAsync = delegate(AsyncAssetBundleLoadingContext ctx)
				{
					HandleCabRandomizePrefix(ctx);
				};
				RegisterAssetBundleLoadingHook(priority, _enableCabRandomizationPrefix);
				RegisterAsyncAssetBundleLoadingHook(priority, _enableCabRandomizationPrefixAsync);
			}
			_enableCabRandomizationPostfix = delegate(AssetBundleLoadedContext ctx)
			{
				HandleCabRandomizePostfix(ctx);
			};
			RegisterAssetBundleLoadedHook(priority, _enableCabRandomizationPostfix);
			void HandleCabRandomizePostfix(AssetBundleLoadedContext context)
			{
				if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromFile)
				{
					if ((Object)(object)context.Bundle == (Object)null && File.Exists(context.Parameters.Path))
					{
						XuaLogger.ResourceRedirector.Warn("The asset bundle '" + context.Parameters.Path + "' could not be loaded likely due to conflicting CAB-string. Retrying in-memory with randomized CAB-string.");
						byte[] array;
						using (FileStream fileStream = new FileStream(context.Parameters.Path, FileMode.Open, FileAccess.Read))
						{
							long length = fileStream.Length;
							long offset = (long)context.Parameters.Offset;
							long num = length - offset;
							fileStream.Seek(offset, SeekOrigin.Begin);
							array = StreamExtensions.ReadFully((Stream)fileStream, (int)num);
						}
						if (!forceRandomizeWhenInMemory)
						{
							CabHelper.RandomizeCabWithAnyLength(array);
						}
						AssetBundle val = AssetBundle.LoadFromMemory(array, 0u);
						if ((Object)(object)val != (Object)null)
						{
							context.Bundle = val;
							context.Complete();
						}
					}
				}
				else if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromMemory)
				{
					if ((Object)(object)context.Bundle == (Object)null && !forceRandomizeWhenInMemory)
					{
						string text = AssetBundleHelper.PathForLoadedInMemoryBundle ?? "Unnamed";
						XuaLogger.ResourceRedirector.Warn("Could not load an in-memory asset bundle (" + text + ") likely due to conflicting CAB-string. Retrying with randomized CAB-string.");
						CabHelper.RandomizeCabWithAnyLength(context.Parameters.Binary);
						AssetBundle val2 = AssetBundle.LoadFromMemory(context.Parameters.Binary, 0u);
						if ((Object)(object)val2 != (Object)null)
						{
							context.Bundle = val2;
							context.Complete();
						}
					}
				}
				else if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromStream && (Object)(object)context.Bundle == (Object)null)
				{
					string text2 = AssetBundleHelper.PathForLoadedInMemoryBundle ?? "Unnamed";
					XuaLogger.ResourceRedirector.Warn("Could not load a stream asset bundle (" + text2 + ") likely due to conflicting CAB-string. Retrying with randomized CAB-string.");
					byte[] array2 = StreamExtensions.ReadFully(context.Parameters.Stream, 0);
					if (!forceRandomizeWhenInMemory)
					{
						CabHelper.RandomizeCabWithAnyLength(array2);
					}
					AssetBundle val3 = AssetBundle.LoadFromMemory(array2, 0u);
					if ((Object)(object)val3 != (Object)null)
					{
						context.Bundle = val3;
						context.Complete();
					}
				}
			}
			static void HandleCabRandomizePrefix(IAssetBundleLoadingContext context)
			{
				if (context.Parameters.LoadType == AssetBundleLoadType.LoadFromMemory)
				{
					CabHelper.RandomizeCabWithAnyLength(context.Parameters.Binary);
				}
			}
		}

		public static void DisableRandomizeCabIfConflict()
		{
			if (_enabledRandomizeCabIfConflict)
			{
				_enabledRandomizeCabIfConflict = false;
				if (_enableCabRandomizationPrefix != null)
				{
					UnregisterAssetBundleLoadingHook(_enableCabRandomizationPrefix);
					_enableCabRandomizationPrefix = null;
				}
				if (_enableCabRandomizationPrefixAsync != null)
				{
					UnregisterAsyncAssetBundleLoadingHook(_enableCabRandomizationPrefixAsync);
					_enableCabRandomizationPrefixAsync = null;
				}
				if (_enableCabRandomizationPostfix != null)
				{
					UnregisterAssetBundleLoadedHook(_enableCabRandomizationPostfix);
					_enableCabRandomizationPostfix = null;
				}
			}
		}

		public static void DisableRedirectMissingAssetBundlesToEmptyAssetBundle()
		{
			if (_redirectionMissingAssetBundlesToEmpty != null && _redirectionMissingAssetBundlesToEmptyAsync != null)
			{
				UnregisterAssetBundleLoadingHook(_redirectionMissingAssetBundlesToEmpty);
				UnregisterAsyncAssetBundleLoadingHook(_redirectionMissingAssetBundlesToEmptyAsync);
				_redirectionMissingAssetBundlesToEmpty = null;
				_redirectionMissingAssetBundlesToEmptyAsync = null;
			}
		}

		internal static bool TryGetAssetBundleLoadInfo(AssetBundleRequest request, out AsyncAssetLoadInfo result)
		{
			result = ExtensionDataHelper.GetExtensionData<AsyncAssetLoadInfo>((object)request);
			return result != null;
		}

		internal static bool TryGetAssetBundle(AssetBundleCreateRequest request, out AsyncAssetBundleLoadInfo result)
		{
			result = ExtensionDataHelper.GetExtensionData<AsyncAssetBundleLoadInfo>((object)request);
			return result != null;
		}

		internal static bool ShouldBlockAsyncOperationMethods(AssetBundleRequest operation)
		{
			if (TryGetAssetBundleLoadInfo(operation, out var result))
			{
				return result.ResolveType == AsyncAssetLoadingResolve.ThroughAssets;
			}
			return false;
		}

		internal static bool ShouldBlockAsyncOperationMethods(AssetBundleCreateRequest operation)
		{
			if (TryGetAssetBundle(operation, out var result))
			{
				return result.ResolveType == AsyncAssetBundleLoadingResolve.ThroughBundle;
			}
			return false;
		}

		internal static bool ShouldBlockAsyncOperationMethods(AsyncOperation operation)
		{
			if (SyncOverAsyncEnabled)
			{
				AssetBundleRequest operation2 = default(AssetBundleRequest);
				if (!ObjectExtensions.TryCastTo<AssetBundleRequest>((object)operation, ref operation2) || !ShouldBlockAsyncOperationMethods(operation2))
				{
					AssetBundleCreateRequest operation3 = default(AssetBundleCreateRequest);
					if (ObjectExtensions.TryCastTo<AssetBundleCreateRequest>((object)operation, ref operation3))
					{
						return ShouldBlockAsyncOperationMethods(operation3);
					}
					return false;
				}
				return true;
			}
			return false;
		}

		internal static AssetBundleLoadingContext Hook_AssetBundleLoading_Prefix(AssetBundleLoadingParameters parameters, out AssetBundle bundle)
		{
			AssetBundleLoadingContext assetBundleLoadingContext = new AssetBundleLoadingContext(parameters);
			if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled))
			{
				bundle = null;
				return assetBundleLoadingContext;
			}
			try
			{
				_isFiringAssetBundle = true;
				if (_logAllLoadedResources)
				{
					XuaLogger.ResourceRedirector.Debug("Loading Asset Bundle: (" + assetBundleLoadingContext.GetNormalizedPath() + ").");
				}
				List<PrioritizedCallback<Delegate>> prefixRedirectionsForAssetBundles = PrefixRedirectionsForAssetBundles;
				int count = prefixRedirectionsForAssetBundles.Count;
				for (int i = 0; i < count; i++)
				{
					PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAssetBundles[i];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						if (prioritizedCallback.Callback is Action<AssetBundleLoadingContext> action)
						{
							action(assetBundleLoadingContext);
						}
						else if (prioritizedCallback.Callback is Action<IAssetBundleLoadingContext> action2)
						{
							action2(assetBundleLoadingContext);
						}
						if (assetBundleLoadingContext.SkipRemainingPrefixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoading event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
			}
			catch (Exception ex2)
			{
				XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetBundleLoading event.");
			}
			finally
			{
				_isFiringAssetBundle = false;
			}
			bundle = assetBundleLoadingContext.Bundle;
			return assetBundleLoadingContext;
		}

		internal static AssetBundleLoadedContext Hook_AssetBundleLoaded_Postfix(AssetBundleLoadingParameters parameters, ref AssetBundle bundle)
		{
			AssetBundleLoadedContext assetBundleLoadedContext = new AssetBundleLoadedContext(parameters, bundle);
			if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled))
			{
				bundle = null;
				return assetBundleLoadedContext;
			}
			try
			{
				_isFiringAssetBundle = true;
				List<PrioritizedCallback<Action<AssetBundleLoadedContext>>> postfixRedirectionsForAssetBundles = PostfixRedirectionsForAssetBundles;
				int count = postfixRedirectionsForAssetBundles.Count;
				for (int i = 0; i < count; i++)
				{
					PrioritizedCallback<Action<AssetBundleLoadedContext>> prioritizedCallback = postfixRedirectionsForAssetBundles[i];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						prioritizedCallback.Callback(assetBundleLoadedContext);
						if (assetBundleLoadedContext.SkipRemainingPostfixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoaded event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
			}
			catch (Exception ex2)
			{
				XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetBundleLoaded event.");
			}
			finally
			{
				_isFiringAssetBundle = false;
			}
			bundle = assetBundleLoadedContext.Bundle;
			return assetBundleLoadedContext;
		}

		internal static AsyncAssetBundleLoadingContext Hook_AssetBundleLoading_Prefix(AssetBundleLoadingParameters parameters, out AssetBundleCreateRequest request)
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			AsyncAssetBundleLoadingContext asyncAssetBundleLoadingContext = new AsyncAssetBundleLoadingContext(parameters);
			if (_isFiringAssetBundle && (_isRecursionDisabledPermanently || !RecursionEnabled))
			{
				request = null;
				return asyncAssetBundleLoadingContext;
			}
			try
			{
				_isFiringAssetBundle = true;
				if (_logAllLoadedResources)
				{
					XuaLogger.ResourceRedirector.Debug("Loading Asset Bundle (async): (" + asyncAssetBundleLoadingContext.GetNormalizedPath() + ").");
				}
				List<PrioritizedCallback<Delegate>> prefixRedirectionsForAsyncAssetBundles = PrefixRedirectionsForAsyncAssetBundles;
				int count = prefixRedirectionsForAsyncAssetBundles.Count;
				for (int i = 0; i < count; i++)
				{
					PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAsyncAssetBundles[i];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						if (prioritizedCallback.Callback is Action<AsyncAssetBundleLoadingContext> action)
						{
							action(asyncAssetBundleLoadingContext);
						}
						else if (prioritizedCallback.Callback is Action<IAssetBundleLoadingContext> action2)
						{
							action2(asyncAssetBundleLoadingContext);
						}
						if (asyncAssetBundleLoadingContext.SkipRemainingPrefixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetBundleLoading event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
			}
			catch (Exception ex2)
			{
				XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AsyncAssetBundleLoading event.");
			}
			finally
			{
				_isFiringAssetBundle = false;
			}
			if (asyncAssetBundleLoadingContext.ResolveType == AsyncAssetBundleLoadingResolve.ThroughRequest)
			{
				request = asyncAssetBundleLoadingContext.Request;
			}
			else
			{
				if (asyncAssetBundleLoadingContext.ResolveType != AsyncAssetBundleLoadingResolve.ThroughBundle)
				{
					throw new InvalidOperationException("Found invalid ResolveType on context: " + asyncAssetBundleLoadingContext.ResolveType);
				}
				request = new AssetBundleCreateRequest();
				if (!asyncAssetBundleLoadingContext.SkipOriginalCall)
				{
					XuaLogger.ResourceRedirector.Warn("Resolving sync over async asset load, but 'SkipOriginalCall' was not set to true. Forcing it to true.");
					asyncAssetBundleLoadingContext.SkipOriginalCall = true;
				}
			}
			return asyncAssetBundleLoadingContext;
		}

		internal static void Hook_AssetBundleLoading_Postfix(AsyncAssetBundleLoadingContext context, AssetBundleCreateRequest request)
		{
			if (request != null)
			{
				ExtensionDataHelper.SetExtensionData<AsyncAssetBundleLoadInfo>((object)request, new AsyncAssetBundleLoadInfo(context.Parameters, context.Bundle, context.SkipAllPostfixes, context.ResolveType));
			}
		}

		internal static void Hook_AssetLoading_Postfix(AsyncAssetLoadingContext context, AssetBundleRequest request)
		{
			if (request != null)
			{
				ExtensionDataHelper.SetExtensionData<AsyncAssetLoadInfo>((object)request, new AsyncAssetLoadInfo(context.Parameters, context.Bundle, context.SkipAllPostfixes, context.ResolveType, context.Assets));
			}
		}

		internal static AssetLoadingContext Hook_AssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle parentBundle, ref Object asset)
		{
			Object[] assets = null;
			AssetLoadingContext result = Hook_AssetLoading_Prefix(parameters, parentBundle, ref assets);
			if (assets == null || assets.Length == 0)
			{
				asset = null;
				return result;
			}
			if (assets.Length > 1)
			{
				XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in AssetLoadeding event. Returned more than one asset to call requiring only a single asset.");
				asset = assets[0];
				return result;
			}
			if (assets.Length == 1)
			{
				asset = assets[0];
			}
			return result;
		}

		internal static AssetLoadingContext Hook_AssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle bundle, ref Object[] assets)
		{
			AssetLoadingContext assetLoadingContext = new AssetLoadingContext(parameters, bundle);
			try
			{
				if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled))
				{
					return assetLoadingContext;
				}
				_isFiringAsset = true;
				List<PrioritizedCallback<Delegate>> prefixRedirectionsForAssetsPerCall = PrefixRedirectionsForAssetsPerCall;
				int count = prefixRedirectionsForAssetsPerCall.Count;
				for (int i = 0; i < count; i++)
				{
					PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAssetsPerCall[i];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						if (prioritizedCallback.Callback is Action<AssetLoadingContext> action)
						{
							action(assetLoadingContext);
						}
						else if (prioritizedCallback.Callback is Action<IAssetLoadingContext> action2)
						{
							action2(assetLoadingContext);
						}
						if (assetLoadingContext.SkipRemainingPrefixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetLoading event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
				assets = assetLoadingContext.Assets;
			}
			catch (Exception ex2)
			{
				XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetLoading event.");
			}
			finally
			{
				_isFiringAsset = false;
			}
			return assetLoadingContext;
		}

		internal static AsyncAssetLoadingContext Hook_AsyncAssetLoading_Prefix(AssetLoadingParameters parameters, AssetBundle bundle, ref AssetBundleRequest request)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			AsyncAssetLoadingContext asyncAssetLoadingContext = new AsyncAssetLoadingContext(parameters, bundle);
			try
			{
				if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled))
				{
					return asyncAssetLoadingContext;
				}
				_isFiringAsset = true;
				List<PrioritizedCallback<Delegate>> prefixRedirectionsForAsyncAssetsPerCall = PrefixRedirectionsForAsyncAssetsPerCall;
				int count = prefixRedirectionsForAsyncAssetsPerCall.Count;
				for (int i = 0; i < count; i++)
				{
					PrioritizedCallback<Delegate> prioritizedCallback = prefixRedirectionsForAsyncAssetsPerCall[i];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						if (prioritizedCallback.Callback is Action<AsyncAssetLoadingContext> action)
						{
							action(asyncAssetLoadingContext);
						}
						else if (prioritizedCallback.Callback is Action<IAssetLoadingContext> action2)
						{
							action2(asyncAssetLoadingContext);
						}
						if (asyncAssetLoadingContext.SkipRemainingPrefixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AsyncAssetLoading event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
				if (asyncAssetLoadingContext.ResolveType == AsyncAssetLoadingResolve.ThroughRequest)
				{
					request = asyncAssetLoadingContext.Request;
				}
				else
				{
					if (asyncAssetLoadingContext.ResolveType != AsyncAssetLoadingResolve.ThroughAssets)
					{
						throw new InvalidOperationException("Found invalid ResolveType on context: " + asyncAssetLoadingContext.ResolveType);
					}
					request = new AssetBundleRequest();
					if (!asyncAssetLoadingContext.SkipOriginalCall)
					{
						XuaLogger.ResourceRedirector.Warn("Resolving sync over async asset load, but 'SkipOriginalCall' was not set to true. Forcing it to true.");
						asyncAssetLoadingContext.SkipOriginalCall = true;
					}
				}
			}
			catch (Exception ex2)
			{
				XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AsyncAssetLoading event.");
			}
			finally
			{
				_isFiringAsset = false;
			}
			return asyncAssetLoadingContext;
		}

		internal static void Hook_AssetLoaded_Postfix(AssetLoadingParameters parameters, AssetBundle parentBundle, ref Object asset)
		{
			Object[] assets = (Object[])(object)((!(asset == (Object)null)) ? new Object[1] { asset } : new Object[0]);
			Hook_AssetLoaded_Postfix(parameters, parentBundle, ref assets);
			if (assets == null || assets.Length == 0)
			{
				asset = null;
			}
			else if (assets.Length > 1)
			{
				XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in AssetLoaded event. Returned more than one asset to call requiring only a single asset.");
				asset = assets[0];
			}
			else if (assets.Length == 1)
			{
				asset = assets[0];
			}
		}

		internal static void Hook_AssetLoaded_Postfix(AssetLoadingParameters parameters, AssetBundle bundle, ref Object[] assets)
		{
			FireAssetLoadedEvent(parameters.ToAssetLoadedParameters(), bundle, ref assets);
		}

		internal static void Hook_ResourceLoaded_Postfix(ResourceLoadedParameters parameters, ref Object asset)
		{
			Object[] assets = (Object[])(object)((!(asset == (Object)null)) ? new Object[1] { asset } : new Object[0]);
			Hook_ResourceLoaded_Postfix(parameters, ref assets);
			if (assets == null || assets.Length == 0)
			{
				asset = null;
			}
			else if (assets.Length > 1)
			{
				XuaLogger.ResourceRedirector.Warn("Illegal behaviour by redirection handler in ResourceLoaded event. Returned more than one asset to call requiring only a single asset.");
				asset = assets[0];
			}
			else if (assets.Length == 1)
			{
				asset = assets[0];
			}
		}

		internal static void Hook_ResourceLoaded_Postfix(ResourceLoadedParameters parameters, ref Object[] assets)
		{
			FireResourceLoadedEvent(parameters, ref assets);
		}

		internal static void FireAssetLoadedEvent(AssetLoadedParameters parameters, AssetBundle assetBundle, ref Object[] assets)
		{
			Object[] array = assets?.ToArray();
			try
			{
				AssetLoadedContext assetLoadedContext = new AssetLoadedContext(parameters, assetBundle, assets);
				if (_isFiringAsset && (_isRecursionDisabledPermanently || !RecursionEnabled))
				{
					return;
				}
				_isFiringAsset = true;
				if (_logAllLoadedResources && assets != null)
				{
					for (int i = 0; i < assets.Length; i++)
					{
						Object val = assets[i];
						if (val != (Object)null)
						{
							string uniqueFileSystemAssetPath = assetLoadedContext.GetUniqueFileSystemAssetPath(val);
							XuaLogger.ResourceRedirector.Debug("Loaded Asset: '" + ObjectExtensions.GetUnityType((object)val).FullName + "', Load Type: '" + parameters.LoadType.ToString() + "', Unique Path: (" + uniqueFileSystemAssetPath + ").");
						}
					}
				}
				List<PrioritizedCallback<Action<AssetLoadedContext>>> postfixRedirectionsForAssetsPerCall = PostfixRedirectionsForAssetsPerCall;
				int count = postfixRedirectionsForAssetsPerCall.Count;
				for (int j = 0; j < count; j++)
				{
					PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback = postfixRedirectionsForAssetsPerCall[j];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						prioritizedCallback.Callback(assetLoadedContext);
						if (assetLoadedContext.SkipRemainingPostfixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking AssetLoaded event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
				assets = assetLoadedContext.Assets;
				if (assetLoadedContext.SkipRemainingPostfixes || assets == null)
				{
					return;
				}
				int num = assets.Length;
				for (int k = 0; k < num; k++)
				{
					Object val2 = assets[k];
					if (val2 != (Object)null)
					{
						AssetLoadedContext assetLoadedContext2 = new AssetLoadedContext(parameters, assetBundle, val2);
						List<PrioritizedCallback<Action<AssetLoadedContext>>> postfixRedirectionsForAssetsPerResource = PostfixRedirectionsForAssetsPerResource;
						int count2 = postfixRedirectionsForAssetsPerResource.Count;
						for (int l = 0; l < count2; l++)
						{
							PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback2 = postfixRedirectionsForAssetsPerResource[l];
							if (prioritizedCallback2.IsBeingCalled)
							{
								continue;
							}
							try
							{
								prioritizedCallback2.IsBeingCalled = true;
								prioritizedCallback2.Callback(assetLoadedContext2);
								if (assetLoadedContext2.Asset != (Object)null)
								{
									assets[k] = assetLoadedContext2.Asset;
								}
								else
								{
									XuaLogger.ResourceRedirector.Warn($"Illegal behaviour by redirection handler in AssetLoaded event. You must not remove an asset reference when hooking with behaviour {HookBehaviour.OneCallbackPerResourceLoaded}.");
								}
								if (assetLoadedContext2.SkipRemainingPostfixes)
								{
									break;
								}
							}
							catch (Exception ex2)
							{
								XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking AssetLoaded event.");
							}
							finally
							{
								RecursionEnabled = true;
								prioritizedCallback2.IsBeingCalled = false;
							}
						}
					}
					else
					{
						XuaLogger.ResourceRedirector.Error("Found unexpected null asset during AssetLoaded event.");
					}
				}
			}
			catch (Exception ex3)
			{
				XuaLogger.ResourceRedirector.Error(ex3, "An error occurred while invoking AssetLoaded event.");
			}
			finally
			{
				_isFiringAsset = false;
				if (array != null)
				{
					Object[] array2 = array;
					for (int m = 0; m < array2.Length; m++)
					{
						ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)array2[m]).HasBeenRedirected = true;
					}
				}
			}
		}

		internal static void FireResourceLoadedEvent(ResourceLoadedParameters parameters, ref Object[] assets)
		{
			Object[] array = assets?.ToArray();
			try
			{
				ResourceLoadedContext resourceLoadedContext = new ResourceLoadedContext(parameters, assets);
				if (_isFiringResource && (_isRecursionDisabledPermanently || !RecursionEnabled))
				{
					return;
				}
				_isFiringResource = true;
				if (_logAllLoadedResources && assets != null)
				{
					for (int i = 0; i < assets.Length; i++)
					{
						Object val = assets[i];
						if (val != (Object)null)
						{
							string uniqueFileSystemAssetPath = resourceLoadedContext.GetUniqueFileSystemAssetPath(val);
							XuaLogger.ResourceRedirector.Debug("Loaded Asset: '" + ObjectExtensions.GetUnityType((object)val).FullName + "', Load Type: '" + parameters.LoadType.ToString() + "', Unique Path: (" + uniqueFileSystemAssetPath + ").");
						}
					}
				}
				List<PrioritizedCallback<Action<ResourceLoadedContext>>> postfixRedirectionsForResourcesPerCall = PostfixRedirectionsForResourcesPerCall;
				int count = postfixRedirectionsForResourcesPerCall.Count;
				for (int j = 0; j < count; j++)
				{
					PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback = postfixRedirectionsForResourcesPerCall[j];
					if (prioritizedCallback.IsBeingCalled)
					{
						continue;
					}
					try
					{
						prioritizedCallback.IsBeingCalled = true;
						prioritizedCallback.Callback(resourceLoadedContext);
						if (resourceLoadedContext.SkipRemainingPostfixes)
						{
							break;
						}
					}
					catch (Exception ex)
					{
						XuaLogger.ResourceRedirector.Error(ex, "An error occurred while invoking ResourceLoaded event.");
					}
					finally
					{
						RecursionEnabled = true;
						prioritizedCallback.IsBeingCalled = false;
					}
				}
				assets = resourceLoadedContext.Assets;
				if (resourceLoadedContext.SkipRemainingPostfixes || assets == null)
				{
					return;
				}
				int num = assets.Length;
				for (int k = 0; k < num; k++)
				{
					Object val2 = assets[k];
					if (val2 != (Object)null)
					{
						ResourceLoadedContext resourceLoadedContext2 = new ResourceLoadedContext(parameters, val2);
						List<PrioritizedCallback<Action<ResourceLoadedContext>>> postfixRedirectionsForResourcesPerResource = PostfixRedirectionsForResourcesPerResource;
						int count2 = postfixRedirectionsForResourcesPerResource.Count;
						for (int l = 0; l < count2; l++)
						{
							PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback2 = postfixRedirectionsForResourcesPerResource[l];
							if (prioritizedCallback2.IsBeingCalled)
							{
								continue;
							}
							try
							{
								prioritizedCallback2.IsBeingCalled = true;
								prioritizedCallback2.Callback(resourceLoadedContext2);
								if (resourceLoadedContext2.Asset != (Object)null)
								{
									assets[k] = resourceLoadedContext2.Asset;
								}
								else
								{
									XuaLogger.ResourceRedirector.Warn($"Illegal behaviour by redirection handler in ResourceLoaded event. You must not remove an asset reference when hooking with behaviour {HookBehaviour.OneCallbackPerResourceLoaded}.");
								}
								if (resourceLoadedContext2.SkipRemainingPostfixes)
								{
									break;
								}
							}
							catch (Exception ex2)
							{
								XuaLogger.ResourceRedirector.Error(ex2, "An error occurred while invoking ResourceLoaded event.");
							}
							finally
							{
								RecursionEnabled = true;
								prioritizedCallback2.IsBeingCalled = false;
							}
						}
					}
					else
					{
						XuaLogger.ResourceRedirector.Error("Found unexpected null asset during ResourceLoaded event.");
					}
				}
			}
			catch (Exception ex3)
			{
				XuaLogger.ResourceRedirector.Error(ex3, "An error occurred while invoking ResourceLoaded event.");
			}
			finally
			{
				_isFiringResource = false;
				if (array != null)
				{
					Object[] array2 = array;
					for (int m = 0; m < array2.Length; m++)
					{
						ExtensionDataHelper.GetOrCreateExtensionData<ResourceExtensionData>((object)array2[m]).HasBeenRedirected = true;
					}
				}
			}
		}

		private static void LogEventRegistration(string eventType, IEnumerable callbacks)
		{
			XuaLogger.ResourceRedirector.Debug("Registered new callback for " + eventType + ".");
			LogNewCallbackOrder(eventType, callbacks);
		}

		private static void LogEventUnregistration(string eventType, IEnumerable callbacks)
		{
			XuaLogger.ResourceRedirector.Debug("Unregistered callback for " + eventType + ".");
			LogNewCallbackOrder(eventType, callbacks);
		}

		private static void LogNewCallbackOrder(string eventType, IEnumerable callbacks)
		{
			if (!LogCallbackOrder)
			{
				return;
			}
			XuaLogger.ResourceRedirector.Debug("New callback order for " + eventType + ":");
			foreach (object callback in callbacks)
			{
				XuaLogger.ResourceRedirector.Debug(callback.ToString());
			}
		}

		public static void RegisterAssetBundleLoadedHook(int priority, Action<AssetBundleLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Action<AssetBundleLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority);
			if (PostfixRedirectionsForAssetBundles.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetBundleLoadedContext>>>(PostfixRedirectionsForAssetBundles, prioritizedCallback);
			LogEventRegistration("AssetBundleLoaded", PostfixRedirectionsForAssetBundles);
		}

		public static void RegisterAssetBundleLoadedHook(Action<AssetBundleLoadedContext> action)
		{
			RegisterAssetBundleLoadedHook(0, action);
		}

		public static void UnregisterAssetBundleLoadedHook(Action<AssetBundleLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PostfixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Action<AssetBundleLoadedContext>> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AssetBundleLoaded", PostfixRedirectionsForAssetBundles);
		}

		public static void RegisterAssetLoadingHook(int priority, Action<AssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAssetsPerCall.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetsPerCall, prioritizedCallback);
			LogEventRegistration("AssetLoading", PrefixRedirectionsForAssetsPerCall);
		}

		public static void RegisterAssetLoadingHook(Action<AssetLoadingContext> action)
		{
			RegisterAssetLoadingHook(0, action);
		}

		public static void UnregisterAssetLoadingHook(Action<AssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AssetLoading", PrefixRedirectionsForAssetsPerCall);
		}

		public static void RegisterAsyncAssetLoadingHook(int priority, Action<AsyncAssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAsyncAssetsPerCall.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetsPerCall, prioritizedCallback);
			LogEventRegistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall);
		}

		public static void RegisterAsyncAssetLoadingHook(Action<AsyncAssetLoadingContext> action)
		{
			RegisterAsyncAssetLoadingHook(0, action);
		}

		public static void UnregisterAsyncAssetLoadingHook(Action<AsyncAssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAsyncAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall);
		}

		public static void RegisterAsyncAndSyncAssetLoadingHook(int priority, Action<IAssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAsyncAssetsPerCall.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetsPerCall, prioritizedCallback);
			LogEventRegistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall);
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetsPerCall, prioritizedCallback);
			LogEventRegistration("AssetLoading", PrefixRedirectionsForAssetsPerCall);
		}

		public static void RegisterAsyncAndSyncAssetLoadingHook(Action<IAssetLoadingContext> action)
		{
			RegisterAsyncAndSyncAssetLoadingHook(0, action);
		}

		public static void UnregisterAsyncAndSyncAssetLoadingHook(Action<IAssetLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAsyncAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AsyncAssetLoading", PrefixRedirectionsForAsyncAssetsPerCall);
			PrefixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AssetLoading", PrefixRedirectionsForAssetsPerCall);
		}

		public static void RegisterAssetLoadedHook(HookBehaviour behaviour, int priority, Action<AssetLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Action<AssetLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority);
			if (PostfixRedirectionsForAssetsPerCall.Contains(prioritizedCallback) || PostfixRedirectionsForAssetsPerResource.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			switch (behaviour)
			{
			case HookBehaviour.OneCallbackPerLoadCall:
				ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetLoadedContext>>>(PostfixRedirectionsForAssetsPerCall, prioritizedCallback);
				LogEventRegistration("AssetLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForAssetsPerCall);
				break;
			case HookBehaviour.OneCallbackPerResourceLoaded:
				ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<AssetLoadedContext>>>(PostfixRedirectionsForAssetsPerResource, prioritizedCallback);
				LogEventRegistration("AssetLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForAssetsPerResource);
				break;
			}
		}

		public static void RegisterAssetLoadedHook(HookBehaviour behaviour, Action<AssetLoadedContext> action)
		{
			RegisterAssetLoadedHook(behaviour, 0, action);
		}

		public static void UnregisterAssetLoadedHook(Action<AssetLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			if (PostfixRedirectionsForAssetsPerCall.RemoveAll((PrioritizedCallback<Action<AssetLoadedContext>> x) => x.Callback == action) > 0)
			{
				LogEventRegistration("AssetLoaded (" + HookBehaviour.OneCallbackPerLoadCall.ToString() + ")", PostfixRedirectionsForAssetsPerCall);
			}
			if (PostfixRedirectionsForAssetsPerResource.RemoveAll((PrioritizedCallback<Action<AssetLoadedContext>> x) => x.Callback == action) > 0)
			{
				LogEventRegistration("AssetLoaded (" + HookBehaviour.OneCallbackPerResourceLoaded.ToString() + ")", PostfixRedirectionsForAssetsPerResource);
			}
		}

		public static void RegisterAssetBundleLoadingHook(int priority, Action<AssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAssetBundles.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetBundles, prioritizedCallback);
			LogEventRegistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles);
		}

		public static void RegisterAssetBundleLoadingHook(Action<AssetBundleLoadingContext> action)
		{
			RegisterAssetBundleLoadingHook(0, action);
		}

		public static void UnregisterAssetBundleLoadingHook(Action<AssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles);
		}

		public static void RegisterAsyncAssetBundleLoadingHook(int priority, Action<AsyncAssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAsyncAssetBundles.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetBundles, prioritizedCallback);
			LogEventRegistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles);
		}

		public static void RegisterAsyncAssetBundleLoadingHook(Action<AsyncAssetBundleLoadingContext> action)
		{
			RegisterAsyncAssetBundleLoadingHook(0, action);
		}

		public static void UnregisterAsyncAssetBundleLoadingHook(Action<AsyncAssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAsyncAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles);
		}

		public static void RegisterAsyncAndSyncAssetBundleLoadingHook(int priority, Action<IAssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Delegate> prioritizedCallback = PrioritizedCallback.Create((Delegate)action, priority);
			if (PrefixRedirectionsForAssetBundles.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAssetBundles, prioritizedCallback);
			LogEventRegistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles);
			ListExtensions.BinarySearchInsert<PrioritizedCallback<Delegate>>(PrefixRedirectionsForAsyncAssetBundles, prioritizedCallback);
			LogEventRegistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles);
		}

		public static void RegisterAsyncAndSyncAssetBundleLoadingHook(Action<IAssetBundleLoadingContext> action)
		{
			RegisterAsyncAndSyncAssetBundleLoadingHook(0, action);
		}

		public static void UnregisterAsyncAndSyncAssetBundleLoadingHook(Action<IAssetBundleLoadingContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrefixRedirectionsForAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AssetBundleLoading", PrefixRedirectionsForAssetBundles);
			PrefixRedirectionsForAsyncAssetBundles.RemoveAll((PrioritizedCallback<Delegate> x) => object.Equals(x.Callback, action));
			LogEventUnregistration("AsyncAssetBundleLoading", PrefixRedirectionsForAsyncAssetBundles);
		}

		public static void RegisterResourceLoadedHook(HookBehaviour behaviour, int priority, Action<ResourceLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			PrioritizedCallback<Action<ResourceLoadedContext>> prioritizedCallback = PrioritizedCallback.Create(action, priority);
			if (PostfixRedirectionsForResourcesPerCall.Contains(prioritizedCallback) || PostfixRedirectionsForResourcesPerResource.Contains(prioritizedCallback))
			{
				throw new ArgumentException("This callback has already been registered.", "action");
			}
			Initialize();
			switch (behaviour)
			{
			case HookBehaviour.OneCallbackPerLoadCall:
				ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<ResourceLoadedContext>>>(PostfixRedirectionsForResourcesPerCall, prioritizedCallback);
				LogEventRegistration("ResourceLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForResourcesPerCall);
				break;
			case HookBehaviour.OneCallbackPerResourceLoaded:
				ListExtensions.BinarySearchInsert<PrioritizedCallback<Action<ResourceLoadedContext>>>(PostfixRedirectionsForResourcesPerResource, prioritizedCallback);
				LogEventRegistration("ResourceLoaded (" + behaviour.ToString() + ")", PostfixRedirectionsForResourcesPerResource);
				break;
			}
		}

		public static void RegisterResourceLoadedHook(HookBehaviour behaviour, Action<ResourceLoadedContext> action)
		{
			RegisterResourceLoadedHook(behaviour, 0, action);
		}

		public static void UnregisterResourceLoadedHook(Action<ResourceLoadedContext> action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			if (PostfixRedirectionsForResourcesPerCall.RemoveAll((PrioritizedCallback<Action<ResourceLoadedContext>> x) => x.Callback == action) > 0)
			{
				LogEventRegistration("ResourceLoaded (" + HookBehaviour.OneCallbackPerLoadCall.ToString() + ")", PostfixRedirectionsForResourcesPerCall);
			}
			if (PostfixRedirectionsForResourcesPerResource.RemoveAll((PrioritizedCallback<Action<ResourceLoadedContext>> x) => x.Callback == action) > 0)
			{
				LogEventRegistration("ResourceLoaded (" + HookBehaviour.OneCallbackPerResourceLoaded.ToString() + ")", PostfixRedirectionsForResourcesPerResource);
			}
		}
	}
}
namespace XUnity.ResourceRedirector.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("XUnity.ResourceRedirector.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] empty => (byte[])ResourceManager.GetObject("empty", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace XUnity.ResourceRedirector.Hooks
{
	internal static class ResourceAndAssetHooks
	{
		public static readonly Type[] GeneralHooks = new Type[21]
		{
			typeof(AssetBundle_LoadFromFileAsync_Hook),
			typeof(AssetBundle_LoadFromFile_Hook),
			typeof(AssetBundle_LoadFromMemoryAsync_Hook),
			typeof(AssetBundle_LoadFromMemory_Hook),
			typeof(AssetBundle_LoadFromStreamAsync_Hook),
			typeof(AssetBundle_LoadFromStream_Hook),
			typeof(AssetBundle_mainAsset_Hook),
			typeof(AssetBundle_returnMainAsset_Hook),
			typeof(AssetBundle_Load_Hook),
			typeof(AssetBundle_LoadAsync_Hook),
			typeof(AssetBundle_LoadAll_Hook),
			typeof(AssetBundle_LoadAsset_Internal_Hook),
			typeof(AssetBundle_LoadAssetAsync_Internal_Hook),
			typeof(AssetBundle_LoadAssetWithSubAssets_Internal_Hook),
			typeof(AssetBundle_LoadAssetWithSubAssetsAsync_Internal_Hook),
			typeof(AssetBundleRequest_asset_Hook),
			typeof(AssetBundleRequest_allAssets_Hook),
			typeof(Resources_Load_Hook),
			typeof(Resources_LoadAll_Hook),
			typeof(Resources_GetBuiltinResource_Old_Hook),
			typeof(Resources_GetBuiltinResource_New_Hook)
		};

		public static readonly Type[] SyncOverAsyncHooks = new Type[10]
		{
			typeof(AssetBundleCreateRequest_assetBundle_Hook),
			typeof(AssetBundleCreateRequest_DisableCompatibilityChecks_Hook),
			typeof(AssetBundleCreateRequest_SetEnableCompatibilityChecks_Hook),
			typeof(AsyncOperation_isDone_Hook),
			typeof(AsyncOperation_progress_Hook),
			typeof(AsyncOperation_priority_Hook),
			typeof(AsyncOperation_set_priority_Hook),
			typeof(AsyncOperation_allowSceneActivation_Hook),
			typeof(AsyncOperation_set_allowSceneActivation_Hook),
			typeof(AsyncOperation_Finalize_Hook)
		};
	}
	internal static class AssetBundleCreateRequest_assetBundle_Hook
	{
		private delegate AssetBundle OriginalMethod(AssetBundleCreateRequest __instance);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundleCreateRequest != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest;
			return AccessToolsShim.Property((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "assetBundle")?.GetGetMethod();
		}

		private static bool Prefix(AssetBundleCreateRequest __instance, ref AssetBundle __result, ref AsyncAssetBundleLoadInfo __state)
		{
			if (ResourceRedirection.TryGetAssetBundle(__instance, out __state))
			{
				if (__state.ResolveType == AsyncAssetBundleLoadingResolve.ThroughBundle)
				{
					__result = __state.Bundle;
					return false;
				}
				return true;
			}
			return true;
		}

		private static void Postfix(ref AssetBundle __result, ref AsyncAssetBundleLoadInfo __state)
		{
			if (__state == null)
			{
				return;
			}
			if (!__state.SkipAllPostfixes)
			{
				ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result);
			}
			if ((Object)(object)__result != (Object)null && __state != null)
			{
				string path = __state.Parameters.Path;
				if (path != null)
				{
					ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = path;
				}
			}
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundle MM_Detour(AssetBundleCreateRequest __instance)
		{
			AssetBundle __result = null;
			AsyncAssetBundleLoadInfo __state = null;
			if (Prefix(__instance, ref __result, ref __state))
			{
				__result = _original(__instance);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundleCreateRequest_DisableCompatibilityChecks_Hook
	{
		private delegate void OriginalMethod(AssetBundleCreateRequest __instance);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest;
			return (object)AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) }) == null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest;
			return AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "DisableCompatibilityChecks", new Type[0]);
		}

		private static bool Prefix(AssetBundleCreateRequest __instance)
		{
			return !ResourceRedirection.ShouldBlockAsyncOperationMethods(__instance);
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static void MM_Detour(AssetBundleCreateRequest __instance)
		{
			if (Prefix(__instance))
			{
				_original(__instance);
			}
		}
	}
	internal static class AssetBundleCreateRequest_SetEnableCompatibilityChecks_Hook
	{
		private delegate void OriginalMethod(AssetBundleCreateRequest __instance, bool set);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest;
			return (object)AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) }) != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundleCreateRequest = UnityTypes.AssetBundleCreateRequest;
			return AccessToolsShim.Method((assetBundleCreateRequest != null) ? assetBundleCreateRequest.ClrType : null, "SetEnableCompatibilityChecks", new Type[1] { typeof(bool) });
		}

		private static bool Prefix(AssetBundleCreateRequest __instance, bool set)
		{
			return !ResourceRedirection.ShouldBlockAsyncOperationMethods(__instance);
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static void MM_Detour(AssetBundleCreateRequest __instance, bool set)
		{
			if (Prefix(__instance, set))
			{
				_original(__instance, set);
			}
		}
	}
	internal static class AssetBundle_LoadFromFileAsync_Hook
	{
		private delegate AssetBundleCreateRequest OriginalMethod(string path, uint crc, ulong offset);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromFileAsync_Internal", new Type[3]
			{
				typeof(string),
				typeof(uint),
				typeof(ulong)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromFileAsync", new Type[3]
				{
					typeof(string),
					typeof(uint),
					typeof(ulong)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref string path, ref uint crc, ref ulong offset, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, path, crc, offset, null, 0u, AssetBundleLoadType.LoadFromFile);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			path = parameters2.Path;
			crc = parameters2.Crc;
			offset = parameters2.Offset;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result);
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundleCreateRequest MM_Detour(string path, uint crc, ulong offset)
		{
			AssetBundleCreateRequest __result = null;
			AsyncAssetBundleLoadingContext __state = null;
			if (Prefix(ref path, ref crc, ref offset, ref __result, ref __state))
			{
				__result = _original(path, crc, offset);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_LoadFromFile_Hook
	{
		private delegate AssetBundle OriginalMethod(string path, uint crc, ulong offset);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromFile_Internal", new Type[3]
			{
				typeof(string),
				typeof(uint),
				typeof(ulong)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromFile", new Type[3]
				{
					typeof(string),
					typeof(uint),
					typeof(ulong)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref string path, ref uint crc, ref ulong offset, ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, path, crc, offset, null, 0u, AssetBundleLoadType.LoadFromFile);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			path = parameters2.Path;
			crc = parameters2.Crc;
			offset = parameters2.Offset;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			if (!__state.SkipAllPostfixes)
			{
				ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result);
			}
			if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null)
			{
				ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path;
			}
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundle MM_Detour(string path, uint crc, ulong offset)
		{
			AssetBundle __result = null;
			AssetBundleLoadingContext __state = null;
			if (Prefix(ref path, ref crc, ref offset, ref __result, ref __state))
			{
				__result = _original(path, crc, offset);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_LoadFromMemoryAsync_Hook
	{
		private delegate AssetBundleCreateRequest OriginalMethod(byte[] binary, uint crc);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromMemoryAsync_Internal", new Type[2]
			{
				typeof(byte[]),
				typeof(uint)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromMemoryAsync", new Type[2]
				{
					typeof(byte[]),
					typeof(uint)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref byte[] binary, ref uint crc, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(binary, null, crc, 0uL, null, 0u, AssetBundleLoadType.LoadFromMemory);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			binary = parameters2.Binary;
			crc = parameters2.Crc;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result);
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundleCreateRequest MM_Detour(byte[] binary, uint crc)
		{
			AssetBundleCreateRequest __result = null;
			AsyncAssetBundleLoadingContext __state = null;
			if (Prefix(ref binary, ref crc, ref __result, ref __state))
			{
				__result = _original(binary, crc);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_LoadFromMemory_Hook
	{
		private delegate AssetBundle OriginalMethod(byte[] binary, uint crc);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromMemory_Internal", new Type[2]
			{
				typeof(byte[]),
				typeof(uint)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromMemory", new Type[2]
				{
					typeof(byte[]),
					typeof(uint)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref byte[] binary, ref uint crc, ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(binary, null, crc, 0uL, null, 0u, AssetBundleLoadType.LoadFromMemory);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			binary = parameters2.Binary;
			crc = parameters2.Crc;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			if (!__state.SkipAllPostfixes)
			{
				ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result);
			}
			if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null)
			{
				ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path;
			}
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundle MM_Detour(byte[] binary, uint crc)
		{
			AssetBundle __result = null;
			AssetBundleLoadingContext __state = null;
			if (Prefix(ref binary, ref crc, ref __result, ref __state))
			{
				__result = _original(binary, crc);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_LoadFromStreamAsync_Hook
	{
		private delegate AssetBundleCreateRequest OriginalMethod(Stream stream, uint crc, uint managedReadBufferSize);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromStreamAsyncInternal", new Type[3]
			{
				typeof(Stream),
				typeof(uint),
				typeof(uint)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromStreamAsync", new Type[3]
				{
					typeof(Stream),
					typeof(uint),
					typeof(uint)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref Stream stream, ref uint crc, ref uint managedReadBufferSize, ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, null, crc, 0uL, stream, managedReadBufferSize, AssetBundleLoadType.LoadFromMemory);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			stream = parameters2.Stream;
			crc = parameters2.Crc;
			managedReadBufferSize = parameters2.ManagedReadBufferSize;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundleCreateRequest __result, ref AsyncAssetBundleLoadingContext __state)
		{
			ResourceRedirection.Hook_AssetBundleLoading_Postfix(__state, __result);
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundleCreateRequest MM_Detour(Stream stream, uint crc, uint managedReadBufferSize)
		{
			AssetBundleCreateRequest __result = null;
			AsyncAssetBundleLoadingContext __state = null;
			if (Prefix(ref stream, ref crc, ref managedReadBufferSize, ref __result, ref __state))
			{
				__result = _original(stream, crc, managedReadBufferSize);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_LoadFromStream_Hook
	{
		private delegate AssetBundle OriginalMethod(Stream stream, uint crc, uint managedReadBufferSize);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			return UnityTypes.AssetBundle != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			MethodInfo methodInfo = AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "LoadFromStreamInternal", new Type[3]
			{
				typeof(Stream),
				typeof(uint),
				typeof(uint)
			});
			if ((object)methodInfo == null)
			{
				TypeContainer assetBundle2 = UnityTypes.AssetBundle;
				methodInfo = AccessToolsShim.Method((assetBundle2 != null) ? assetBundle2.ClrType : null, "LoadFromStream", new Type[3]
				{
					typeof(Stream),
					typeof(uint),
					typeof(uint)
				});
			}
			return methodInfo;
		}

		private static bool Prefix(ref Stream stream, ref uint crc, ref uint managedReadBufferSize, ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			AssetBundleLoadingParameters parameters = new AssetBundleLoadingParameters(null, null, crc, 0uL, stream, managedReadBufferSize, AssetBundleLoadType.LoadFromMemory);
			__state = ResourceRedirection.Hook_AssetBundleLoading_Prefix(parameters, out __result);
			AssetBundleLoadingParameters parameters2 = __state.Parameters;
			stream = parameters2.Stream;
			crc = parameters2.Crc;
			managedReadBufferSize = parameters2.ManagedReadBufferSize;
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(ref AssetBundle __result, ref AssetBundleLoadingContext __state)
		{
			if (!__state.SkipAllPostfixes)
			{
				ResourceRedirection.Hook_AssetBundleLoaded_Postfix(__state.Parameters, ref __result);
			}
			if ((Object)(object)__result != (Object)null && __state.Parameters.Path != null)
			{
				ExtensionDataHelper.GetOrCreateExtensionData<AssetBundleExtensionData>((object)__result).Path = __state.Parameters.Path;
			}
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static AssetBundle MM_Detour(Stream stream, uint crc, uint managedReadBufferSize)
		{
			AssetBundle __result = null;
			AssetBundleLoadingContext __state = null;
			if (Prefix(ref stream, ref crc, ref managedReadBufferSize, ref __result, ref __state))
			{
				__result = _original(stream, crc, managedReadBufferSize);
			}
			Postfix(ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_mainAsset_Hook
	{
		private delegate Object OriginalMethod(AssetBundle __instance);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			return (object)AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "returnMainAsset", new Type[1] { typeof(AssetBundle) }) == null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			return AccessToolsShim.Property((assetBundle != null) ? assetBundle.ClrType : null, "mainAsset")?.GetGetMethod();
		}

		private static bool Prefix(AssetBundle __instance, ref Object __result, ref AssetLoadingContext __state)
		{
			AssetLoadingParameters parameters = new AssetLoadingParameters(null, null, AssetLoadType.LoadMainAsset);
			__state = ResourceRedirection.Hook_AssetLoading_Prefix(parameters, __instance, ref __result);
			return !__state.SkipOriginalCall;
		}

		private static void Postfix(AssetBundle __instance, ref Object __result, ref AssetLoadingContext __state)
		{
			if (!__state.SkipAllPostfixes)
			{
				ResourceRedirection.Hook_AssetLoaded_Postfix(__state.Parameters, __instance, ref __result);
			}
		}

		private static void MM_Init(object detour)
		{
			_original = DetourExtensions.GenerateTrampolineEx<OriginalMethod>(detour);
		}

		private static Object MM_Detour(AssetBundle __instance)
		{
			Object __result = null;
			AssetLoadingContext __state = null;
			if (Prefix(__instance, ref __result, ref __state))
			{
				__result = _original(__instance);
			}
			Postfix(__instance, ref __result, ref __state);
			return __result;
		}
	}
	internal static class AssetBundle_returnMainAsset_Hook
	{
		private delegate Object OriginalMethod(AssetBundle __instance);

		private static OriginalMethod _original;

		private static bool Prepare(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			return (object)AccessToolsShim.Method((assetBundle != null) ? assetBundle.ClrType : null, "returnMainAsset", new Type[1] { typeof(AssetBundle) }) != null;
		}

		private static MethodBase TargetMethod(object instance)
		{
			TypeContainer assetBundle = UnityTypes.AssetBundle;
			return AccessToolsShim.Method((assetBundle != null) ? assetBu

mods/x753-Mimics-2.3.2/BepInEx/plugins/Mimics.dll

Decompiled 10 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyMimics.Properties;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Mimics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds mimics to Lethal Company")]
[assembly: AssemblyFileVersion("2.3.2.0")]
[assembly: AssemblyInformationalVersion("2.3.2")]
[assembly: AssemblyProduct("Mimics")]
[assembly: AssemblyTitle("Mimics")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.2.0")]
[module: UnverifiableCode]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
namespace LethalCompanyMimics.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LethalCompanyMimics.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] mimicdoor
		{
			get
			{
				object @object = ResourceManager.GetObject("mimicdoor", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace Mimics
{
	[BepInPlugin("x753.Mimics", "Mimics", "2.3.2")]
	public class Mimics : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GameNetworkManager))]
		internal class GameNetworkManagerPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch()
			{
				((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().AddNetworkPrefab(MimicNetworkerPrefab);
			}
		}

		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartOfRoundPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch(ref StartOfRound __instance)
			{
				if (((NetworkBehaviour)__instance).IsServer && (Object)(object)MimicNetworker.Instance == (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(MimicNetworkerPrefab);
					val.GetComponent<NetworkObject>().Spawn(true);
					MimicNetworker.SpawnWeight0.Value = SpawnRates[0];
					MimicNetworker.SpawnWeight1.Value = SpawnRates[1];
					MimicNetworker.SpawnWeight2.Value = SpawnRates[2];
					MimicNetworker.SpawnWeight3.Value = SpawnRates[3];
					MimicNetworker.SpawnWeight4.Value = SpawnRates[4];
					MimicNetworker.SpawnWeightMax.Value = SpawnRates[5];
					MimicNetworker.SpawnRateDynamic.Value = DynamicSpawnRate;
				}
			}
		}

		[HarmonyPatch(typeof(Terminal))]
		internal class TerminalPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch(ref StartOfRound __instance)
			{
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Expected O, but got Unknown
				Terminal val = Object.FindObjectOfType<Terminal>();
				if (!Object.op_Implicit((Object)(object)val.enemyFiles.Find((TerminalNode node) => node.creatureName == "Mimics")))
				{
					MimicCreatureID = val.enemyFiles.Count;
					MimicFile.creatureFileID = MimicCreatureID;
					val.enemyFiles.Add(MimicFile);
					TerminalKeyword val2 = val.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
					TerminalKeyword val3 = new TerminalKeyword
					{
						word = "mimics",
						isVerb = false,
						defaultVerb = val2
					};
					List<CompatibleNoun> list = val2.compatibleNouns.ToList();
					list.Add(new CompatibleNoun
					{
						noun = val3,
						result = MimicFile
					});
					val2.compatibleNouns = list.ToArray();
					List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
					list2.Add(val3);
					val.terminalNodes.allKeywords = list2.ToArray();
				}
			}
		}

		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("SetExitIDs")]
			[HarmonyPostfix]
			private static void SetExitIDsPatch(ref RoundManager __instance, Vector3 mainEntrancePosition)
			{
				//IL_0536: Unknown result type (might be due to invalid IL or missing references)
				//IL_0547: Unknown result type (might be due to invalid IL or missing references)
				//IL_054c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0551: Unknown result type (might be due to invalid IL or missing references)
				//IL_0556: Unknown result type (might be due to invalid IL or missing references)
				//IL_0235: Unknown result type (might be due to invalid IL or missing references)
				//IL_0241: Unknown result type (might be due to invalid IL or missing references)
				//IL_0255: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0272: Unknown result type (might be due to invalid IL or missing references)
				//IL_0286: Unknown result type (might be due to invalid IL or missing references)
				//IL_0296: Unknown result type (might be due to invalid IL or missing references)
				//IL_029b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_0565: Unknown result type (might be due to invalid IL or missing references)
				//IL_056a: Unknown result type (might be due to invalid IL or missing references)
				//IL_056c: Unknown result type (might be due to invalid IL or missing references)
				//IL_056e: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_06da: Unknown result type (might be due to invalid IL or missing references)
				//IL_06de: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_033d: Unknown result type (might be due to invalid IL or missing references)
				//IL_034e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0353: Unknown result type (might be due to invalid IL or missing references)
				//IL_0358: Unknown result type (might be due to invalid IL or missing references)
				//IL_035d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0367: Unknown result type (might be due to invalid IL or missing references)
				//IL_036c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0371: Unknown result type (might be due to invalid IL or missing references)
				//IL_0377: Unknown result type (might be due to invalid IL or missing references)
				//IL_037f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0388: Unknown result type (might be due to invalid IL or missing references)
				//IL_0392: Unknown result type (might be due to invalid IL or missing references)
				//IL_067b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0414: Unknown result type (might be due to invalid IL or missing references)
				//IL_041c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0425: Unknown result type (might be due to invalid IL or missing references)
				//IL_042f: Unknown result type (might be due to invalid IL or missing references)
				//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_07dd: Expected O, but got Unknown
				//IL_08ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_08d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_084d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0874: Unknown result type (might be due to invalid IL or missing references)
				//IL_0987: Unknown result type (might be due to invalid IL or missing references)
				//IL_09ae: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				MimicDoor.allMimics = new List<MimicDoor>();
				int num = 0;
				Dungeon currentDungeon = __instance.dungeonGenerator.Generator.CurrentDungeon;
				if (!((Object)currentDungeon.DungeonFlow).name.StartsWith("Level1") && !((Object)currentDungeon.DungeonFlow).name.StartsWith("Level2"))
				{
					return;
				}
				int num2 = 0;
				int[] array = new int[6]
				{
					MimicNetworker.SpawnWeight0.Value,
					MimicNetworker.SpawnWeight1.Value,
					MimicNetworker.SpawnWeight2.Value,
					MimicNetworker.SpawnWeight3.Value,
					MimicNetworker.SpawnWeight4.Value,
					MimicNetworker.SpawnWeightMax.Value
				};
				int num3 = 0;
				int[] array2 = array;
				foreach (int num4 in array2)
				{
					num3 += num4;
				}
				Random random = new Random(StartOfRound.Instance.randomMapSeed + 753);
				int num5 = random.Next(0, num3);
				int num6 = 0;
				for (int j = 0; j < array.Length; j++)
				{
					if (num5 < array[j] + num6)
					{
						num2 = j;
						break;
					}
					num6 += array[j];
				}
				if (num2 == 5)
				{
					num2 = 999;
				}
				EntranceTeleport[] array3 = Object.FindObjectsOfType<EntranceTeleport>(false);
				int num7 = (array3.Length - 2) / 2;
				if (MimicNetworker.SpawnRateDynamic.Value && num2 < num7 && num7 > 1)
				{
					num2 += random.Next(0, 2);
				}
				if (MimicNetworker.SpawnRateDynamic.Value && currentDungeon.AllTiles.Count > 100)
				{
					num2 += random.Next(0, 2);
				}
				List<Doorway> list = new List<Doorway>();
				Bounds val2 = default(Bounds);
				foreach (Tile allTile in currentDungeon.AllTiles)
				{
					foreach (Doorway unusedDoorway in allTile.UnusedDoorways)
					{
						if (unusedDoorway.HasDoorPrefabInstance || (Object)(object)((Component)unusedDoorway).GetComponentInChildren<SpawnSyncedObject>(true) == (Object)null)
						{
							continue;
						}
						GameObject gameObject = ((Component)((Component)((Component)unusedDoorway).GetComponentInChildren<SpawnSyncedObject>(true)).transform.parent).gameObject;
						if (!((Object)gameObject).name.StartsWith("AlleyExitDoorContainer") || gameObject.activeSelf)
						{
							continue;
						}
						bool flag = false;
						Matrix4x4 val = Matrix4x4.TRS(((Component)unusedDoorway).transform.position, ((Component)unusedDoorway).transform.rotation, new Vector3(1f, 1f, 1f));
						((Bounds)(ref val2))..ctor(new Vector3(0f, 1.5f, 5.5f), new Vector3(2f, 6f, 8f));
						((Bounds)(ref val2)).center = ((Matrix4x4)(ref val)).MultiplyPoint3x4(((Bounds)(ref val2)).center);
						Collider[] array4 = Physics.OverlapBox(((Bounds)(ref val2)).center, ((Bounds)(ref val2)).extents, ((Component)unusedDoorway).transform.rotation, LayerMask.GetMask(new string[3] { "Room", "Railing", "MapHazards" }));
						Collider[] array5 = array4;
						int num8 = 0;
						if (num8 < array5.Length)
						{
							Collider val3 = array5[num8];
							flag = true;
						}
						if (flag)
						{
							continue;
						}
						foreach (Tile allTile2 in currentDungeon.AllTiles)
						{
							if (!((Object)(object)allTile == (Object)(object)allTile2))
							{
								Vector3 origin = ((Component)unusedDoorway).transform.position + 5f * ((Component)unusedDoorway).transform.forward;
								Bounds val4 = UnityUtil.CalculateProxyBounds(((Component)allTile2).gameObject, true, Vector3.up);
								Ray val5 = default(Ray);
								((Ray)(ref val5)).origin = origin;
								((Ray)(ref val5)).direction = Vector3.up;
								if (((Bounds)(ref val4)).IntersectRay(val5) && (((Object)allTile2).name.Contains("Catwalk") || ((Object)allTile2).name.Contains("LargeForkTile") || ((Object)allTile2).name.Contains("4x4BigStair") || ((Object)allTile2).name.Contains("ElevatorConnector") || (((Object)allTile2).name.Contains("StartRoom") && !((Object)allTile2).name.Contains("Manor"))))
								{
									flag = true;
								}
								val5 = default(Ray);
								((Ray)(ref val5)).origin = origin;
								((Ray)(ref val5)).direction = Vector3.down;
								if (((Bounds)(ref val4)).IntersectRay(val5) && (((Object)allTile2).name.Contains("MediumRoomHallway1B") || ((Object)allTile2).name.Contains("LargeForkTile") || ((Object)allTile2).name.Contains("4x4BigStair") || ((Object)allTile2).name.Contains("ElevatorConnector") || ((Object)allTile2).name.Contains("StartRoom")))
								{
									flag = true;
								}
							}
						}
						if (!flag)
						{
							list.Add(unusedDoorway);
						}
					}
				}
				Shuffle(list, StartOfRound.Instance.randomMapSeed);
				List<Vector3> list2 = new List<Vector3>();
				foreach (Doorway item in list)
				{
					if (num >= num2)
					{
						break;
					}
					bool flag2 = false;
					Vector3 val6 = ((Component)item).transform.position + 5f * ((Component)item).transform.forward;
					foreach (Vector3 item2 in list2)
					{
						if (Vector3.Distance(val6, item2) < 4f)
						{
							flag2 = true;
							break;
						}
					}
					if (flag2)
					{
						continue;
					}
					list2.Add(val6);
					GameObject gameObject2 = ((Component)((Component)((Component)item).GetComponentInChildren<SpawnSyncedObject>(true)).transform.parent).gameObject;
					GameObject val7 = Object.Instantiate<GameObject>(MimicPrefab, ((Component)item).transform);
					val7.transform.position = gameObject2.transform.position;
					MimicDoor component = val7.GetComponent<MimicDoor>();
					component.scanNode.creatureScanID = MimicCreatureID;
					AudioSource[] componentsInChildren = val7.GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource val8 in componentsInChildren)
					{
						val8.volume = MimicVolume / 100f;
						val8.outputAudioMixerGroup = StartOfRound.Instance.ship3DAudio.outputAudioMixerGroup;
					}
					if (SpawnRates[5] == 9753 && num == 0)
					{
						val7.transform.position = new Vector3(-7f, 0f, -10f);
					}
					MimicDoor.allMimics.Add(component);
					component.mimicIndex = num;
					num++;
					GameObject gameObject3 = ((Component)((Component)item).transform.GetChild(0)).gameObject;
					gameObject3.SetActive(false);
					Bounds bounds = ((Collider)component.frameBox).bounds;
					Vector3 center = ((Bounds)(ref bounds)).center;
					bounds = ((Collider)component.frameBox).bounds;
					Collider[] array6 = Physics.OverlapBox(center, ((Bounds)(ref bounds)).extents, Quaternion.identity);
					foreach (Collider val9 in array6)
					{
						if (((Object)((Component)val9).gameObject).name.Contains("Shelf"))
						{
							((Component)val9).gameObject.SetActive(false);
						}
					}
					Light componentInChildren = gameObject2.GetComponentInChildren<Light>(true);
					((Component)componentInChildren).transform.parent.SetParent(val7.transform);
					MeshRenderer[] componentsInChildren2 = val7.GetComponentsInChildren<MeshRenderer>();
					MeshRenderer[] array7 = componentsInChildren2;
					foreach (MeshRenderer val10 in array7)
					{
						Material[] materials = ((Renderer)val10).materials;
						foreach (Material val11 in materials)
						{
							val11.shader = ((Renderer)gameObject3.GetComponentInChildren<MeshRenderer>(true)).material.shader;
							val11.renderQueue = ((Renderer)gameObject3.GetComponentInChildren<MeshRenderer>(true)).material.renderQueue;
						}
					}
					component.interactTrigger.onInteract = new InteractEvent();
					((UnityEvent<PlayerControllerB>)(object)component.interactTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)component.TouchMimic);
					if (MimicPerfection)
					{
						continue;
					}
					component.interactTrigger.timeToHold = 0.9f;
					if (!ColorBlindMode)
					{
						if ((StartOfRound.Instance.randomMapSeed + num) % 2 == 0)
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.490566f, 0.1226415f, 0.1302275f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(0.4339623f, 0.1043965f, 0.1150277f);
							componentInChildren.colorTemperature = 1250f;
						}
						else
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.5f, 0.1580188f, 0.1657038f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(43f / 106f, 0.1358579f, 0.1393619f);
							componentInChildren.colorTemperature = 1300f;
						}
					}
					else if ((StartOfRound.Instance.randomMapSeed + num) % 2 == 0)
					{
						component.interactTrigger.timeToHold = 1.1f;
					}
					else
					{
						component.interactTrigger.timeToHold = 1f;
					}
					if (!EasyMode)
					{
						continue;
					}
					Random random2 = new Random(StartOfRound.Instance.randomMapSeed + num);
					switch (random2.Next(0, 4))
					{
					case 0:
						if (!ColorBlindMode)
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.489f, 0.2415526f, 0.1479868f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(0.489f, 0.2415526f, 0.1479868f);
						}
						else
						{
							component.interactTrigger.timeToHold = 1.5f;
						}
						break;
					case 1:
						component.interactTrigger.hoverTip = "Feed : [LMB]";
						component.interactTrigger.holdTip = "Feed : [LMB]";
						break;
					case 2:
						component.interactTrigger.hoverIcon = component.LostFingersIcon;
						break;
					case 3:
						component.interactTrigger.holdTip = "DIE : [LMB]";
						component.interactTrigger.timeToHold = 0.5f;
						break;
					default:
						component.interactTrigger.hoverTip = "BUG, REPORT TO DEVELOPER";
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem))]
		internal class SprayPaintItemPatch
		{
			private static FieldInfo SprayHit = typeof(SprayPaintItem).GetField("sprayHit", BindingFlags.Instance | BindingFlags.NonPublic);

			[HarmonyPatch("SprayPaintClientRpc")]
			[HarmonyPostfix]
			private static void SprayPaintClientRpcPatch(SprayPaintItem __instance, Vector3 sprayPos, Vector3 sprayRot)
			{
				//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)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				RaycastHit val = (RaycastHit)SprayHit.GetValue(__instance);
				if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null && ((Object)((RaycastHit)(ref val)).collider).name == "MimicSprayCollider")
				{
					MimicDoor component = ((Component)((Component)((RaycastHit)(ref val)).collider).transform.parent.parent).GetComponent<MimicDoor>();
					component.sprayCount++;
					if (component.sprayCount > 8)
					{
						MimicNetworker.Instance.MimicAddAnger(1, component.mimicIndex);
					}
				}
			}
		}

		[HarmonyPatch(typeof(LockPicker))]
		internal class LockPickerPatch
		{
			private static FieldInfo RayHit = typeof(LockPicker).GetField("hit", BindingFlags.Instance | BindingFlags.NonPublic);

			[HarmonyPatch("ItemActivate")]
			[HarmonyPostfix]
			private static void ItemActivatePatch(LockPicker __instance, bool used, bool buttonDown = true)
			{
				//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_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				RaycastHit val = (RaycastHit)RayHit.GetValue(__instance);
				if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) && !((object)(RaycastHit)(ref val)).Equals((object)default(RaycastHit)) && !((Object)(object)((RaycastHit)(ref val)).transform.parent == (Object)null))
				{
					Transform parent = ((RaycastHit)(ref val)).transform.parent;
					if (((Object)parent).name.StartsWith("MimicDoor"))
					{
						MimicNetworker.Instance.MimicLockPick(__instance, ((Component)parent).GetComponent<MimicDoor>().mimicIndex);
					}
				}
			}
		}

		private const string modGUID = "x753.Mimics";

		private const string modName = "Mimics";

		private const string modVersion = "2.3.2";

		private readonly Harmony harmony = new Harmony("x753.Mimics");

		private static Mimics Instance;

		public static GameObject MimicPrefab;

		public static GameObject MimicNetworkerPrefab;

		public static TerminalNode MimicFile;

		public static int MimicCreatureID;

		public static int[] SpawnRates;

		public static bool MimicPerfection;

		public static bool EasyMode;

		public static bool ColorBlindMode;

		public static float MimicVolume;

		public static bool DynamicSpawnRate;

		private void Awake()
		{
			AssetBundle val = AssetBundle.LoadFromMemory(Resources.mimicdoor);
			MimicPrefab = val.LoadAsset<GameObject>("Assets/MimicDoor.prefab");
			MimicNetworkerPrefab = val.LoadAsset<GameObject>("Assets/MimicNetworker.prefab");
			MimicFile = val.LoadAsset<TerminalNode>("Assets/MimicFile.asset");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Mimics is loaded!");
			SpawnRates = new int[6]
			{
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Zero Mimics", 23, "Weight of zero mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "One Mimic", 69, "Weight of one mimic spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Two Mimics", 7, "Weight of two mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Three Mimics", 1, "Weight of three mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Four Mimics", 0, "Weight of four mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Maximum Mimics", 0, "Weight of maximum mimics spawning").Value
			};
			DynamicSpawnRate = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Rate", "Dynamic Spawn Rate", true, "Increases mimic spawn rate based on dungeon size and the number of instances of the real thing.").Value;
			MimicPerfection = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Perfect Mimics", false, "Select this if you want mimics to be the exact same color as the real thing. Overrides all difficulty settings.").Value;
			EasyMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Easy Mode", false, "Each mimic will have one of several possible imperfections to help you tell if it's a mimic.").Value;
			ColorBlindMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Color Blind Mode", false, "Replaces all color differences with another way to differentiate mimics.").Value;
			MimicVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SFX Volume", 100, "Volume of the mimic's SFX (0-100)").Value;
			if (MimicVolume < 0f)
			{
				MimicVolume = 0f;
			}
			if (MimicVolume > 100f)
			{
				MimicVolume = 100f;
			}
			((BaseUnityPlugin)this).Config.Bind<int>("Difficulty", "Difficulty Level", 0, "This is an old setting, ignore it.");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Difficulty", "Difficulty Level"].Definition);
			((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Five Mimics", 0, "This is an old setting, ignore it.");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Spawn Rate", "Five Mimics"].Definition);
			((BaseUnityPlugin)this).Config.Save();
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		public static void Shuffle<T>(IList<T> list, int seed)
		{
			Random random = new Random(seed);
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = random.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}
	}
	public class MimicNetworker : NetworkBehaviour
	{
		public static MimicNetworker Instance;

		public static NetworkVariable<int> SpawnWeight0 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight1 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight2 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight3 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight4 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeightMax = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<bool> SpawnRateDynamic = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private void Awake()
		{
			Instance = this;
		}

		public void MimicAttack(int playerId, int mimicIndex, bool ownerOnly = false)
		{
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicAttackClientRpc(playerId, mimicIndex);
			}
			else if (!ownerOnly)
			{
				Instance.MimicAttackServerRpc(playerId, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicAttackClientRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2885019175u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2885019175u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].Attack(playerId));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicAttackServerRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1024971481u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1024971481u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicAttackClientRpc(playerId, mimicIndex);
				}
			}
		}

		public void MimicAddAnger(int amount, int mimicIndex)
		{
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicAddAngerClientRpc(amount, mimicIndex);
			}
			else
			{
				Instance.MimicAddAngerServerRpc(amount, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicAddAngerClientRpc(int amount, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1137632670u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, amount);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1137632670u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].AddAnger(amount));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicAddAngerServerRpc(int amount, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(669208889u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, amount);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 669208889u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicAddAngerClientRpc(amount, mimicIndex);
				}
			}
		}

		public void MimicLockPick(LockPicker lockPicker, int mimicIndex, bool ownerOnly = false)
		{
			int playerId = (int)((GrabbableObject)lockPicker).playerHeldBy.playerClientId;
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicLockPickClientRpc(playerId, mimicIndex);
			}
			else if (!ownerOnly)
			{
				Instance.MimicLockPickServerRpc(playerId, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicLockPickClientRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3716888238u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3716888238u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].MimicLockPick(playerId));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicLockPickServerRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1897916243u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1897916243u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicLockPickClientRpc(playerId, mimicIndex);
				}
			}
		}

		protected override void __initializeVariables()
		{
			if (SpawnWeight0 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight0 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight0).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight0, "SpawnWeight0");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight0);
			if (SpawnWeight1 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight1 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight1).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight1, "SpawnWeight1");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight1);
			if (SpawnWeight2 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight2 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight2).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight2, "SpawnWeight2");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight2);
			if (SpawnWeight3 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight3 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight3).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight3, "SpawnWeight3");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight3);
			if (SpawnWeight4 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight4 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight4).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight4, "SpawnWeight4");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight4);
			if (SpawnWeightMax == null)
			{
				throw new Exception("MimicNetworker.SpawnWeightMax cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeightMax).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeightMax, "SpawnWeightMax");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeightMax);
			if (SpawnRateDynamic == null)
			{
				throw new Exception("MimicNetworker.SpawnRateDynamic cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnRateDynamic).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnRateDynamic, "SpawnRateDynamic");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnRateDynamic);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_MimicNetworker()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2885019175u, new RpcReceiveHandler(__rpc_handler_2885019175));
			NetworkManager.__rpc_func_table.Add(1024971481u, new RpcReceiveHandler(__rpc_handler_1024971481));
			NetworkManager.__rpc_func_table.Add(1137632670u, new RpcReceiveHandler(__rpc_handler_1137632670));
			NetworkManager.__rpc_func_table.Add(669208889u, new RpcReceiveHandler(__rpc_handler_669208889));
			NetworkManager.__rpc_func_table.Add(3716888238u, new RpcReceiveHandler(__rpc_handler_3716888238));
			NetworkManager.__rpc_func_table.Add(1897916243u, new RpcReceiveHandler(__rpc_handler_1897916243));
		}

		private static void __rpc_handler_2885019175(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicAttackClientRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1024971481(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicAttackServerRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1137632670(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int amount = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref amount);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicAddAngerClientRpc(amount, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_669208889(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int amount = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref amount);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicAddAngerServerRpc(amount, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3716888238(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicLockPickClientRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1897916243(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicLockPickServerRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "MimicNetworker";
		}
	}
	public class MimicDoor : MonoBehaviour
	{
		public GameObject playerTarget;

		public BoxCollider frameBox;

		public Sprite LostFingersIcon;

		public Animator mimicAnimator;

		public GameObject grabPoint;

		public InteractTrigger interactTrigger;

		public ScanNodeProperties scanNode;

		public int anger;

		public bool angering;

		public int sprayCount;

		private bool attacking;

		public static List<MimicDoor> allMimics;

		public int mimicIndex;

		private static MethodInfo RetractClaws = typeof(LockPicker).GetMethod("RetractClaws", BindingFlags.Instance | BindingFlags.NonPublic);

		public void TouchMimic(PlayerControllerB player)
		{
			if (!attacking)
			{
				MimicNetworker.Instance.MimicAttack((int)player.playerClientId, mimicIndex);
			}
		}

		public IEnumerator Attack(int playerId)
		{
			attacking = true;
			interactTrigger.interactable = false;
			PlayerControllerB player = StartOfRound.Instance.allPlayerScripts[playerId];
			mimicAnimator.SetTrigger("Attack");
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)frameBox).transform.position);
			if (num < 8f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
			else if (num < 14f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			yield return (object)new WaitForSeconds(0.2f);
			if (((NetworkBehaviour)player).IsOwner && Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.position) < 8.75f)
			{
				player.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0);
			}
			float startTime = Time.timeSinceLevelLoad;
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)player.deadBody != (Object)null || Time.timeSinceLevelLoad - startTime > 4f));
			if ((Object)(object)player.deadBody != (Object)null)
			{
				player.deadBody.attachedTo = grabPoint.transform;
				player.deadBody.attachedLimb = player.deadBody.bodyParts[5];
				player.deadBody.matchPositionExactly = true;
				for (int i = 0; i < player.deadBody.bodyParts.Length; i++)
				{
					((Component)player.deadBody.bodyParts[i]).GetComponent<Collider>().excludeLayers = LayerMask.op_Implicit(-1);
				}
			}
			yield return (object)new WaitForSeconds(2f);
			if ((Object)(object)player.deadBody != (Object)null)
			{
				player.deadBody.attachedTo = null;
				player.deadBody.attachedLimb = null;
				player.deadBody.matchPositionExactly = false;
				((Component)((Component)player.deadBody).transform.GetChild(0)).gameObject.SetActive(false);
				player.deadBody = null;
			}
			yield return (object)new WaitForSeconds(4.5f);
			attacking = false;
			interactTrigger.interactable = true;
		}

		public IEnumerator MimicLockPick(int playerId)
		{
			if (angering || attacking)
			{
				yield break;
			}
			LockPicker lockPicker = default(LockPicker);
			ref LockPicker reference = ref lockPicker;
			GrabbableObject currentlyHeldObjectServer = StartOfRound.Instance.allPlayerScripts[playerId].currentlyHeldObjectServer;
			reference = (LockPicker)(object)((currentlyHeldObjectServer is LockPicker) ? currentlyHeldObjectServer : null);
			if ((Object)(object)lockPicker == (Object)null)
			{
				yield break;
			}
			attacking = true;
			interactTrigger.interactable = false;
			AudioSource component = ((Component)lockPicker).GetComponent<AudioSource>();
			component.PlayOneShot(lockPicker.placeLockPickerClips[Random.Range(0, lockPicker.placeLockPickerClips.Length)]);
			lockPicker.armsAnimator.SetBool("mounted", true);
			lockPicker.armsAnimator.SetBool("picking", true);
			component.Play();
			component.pitch = Random.Range(0.94f, 1.06f);
			lockPicker.isOnDoor = true;
			lockPicker.isPickingLock = true;
			((GrabbableObject)lockPicker).grabbable = false;
			if (((NetworkBehaviour)lockPicker).IsOwner)
			{
				((GrabbableObject)lockPicker).playerHeldBy.DiscardHeldObject(true, ((NetworkBehaviour)MimicNetworker.Instance).NetworkObject, ((Component)this).transform.position + ((Component)this).transform.up * 1.5f - ((Component)this).transform.forward * 1.15f, true);
			}
			float startTime = Time.timeSinceLevelLoad;
			yield return (object)new WaitUntil((Func<bool>)(() => !((GrabbableObject)lockPicker).isHeld || Time.timeSinceLevelLoad - startTime > 10f));
			((Component)lockPicker).transform.localEulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, ((Component)this).transform.eulerAngles.y + 90f, ((Component)this).transform.eulerAngles.z);
			yield return (object)new WaitForSeconds(5f);
			RetractClaws.Invoke(lockPicker, null);
			((Component)lockPicker).transform.SetParent((Transform)null);
			((GrabbableObject)lockPicker).startFallingPosition = ((Component)lockPicker).transform.position;
			((GrabbableObject)lockPicker).FallToGround(false);
			((GrabbableObject)lockPicker).grabbable = true;
			yield return (object)new WaitForSeconds(1f);
			anger = 3;
			attacking = false;
			interactTrigger.interactable = false;
			PlayerControllerB val = null;
			float num = 9999f;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val2 in allPlayerScripts)
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
				if (num2 < num)
				{
					num = num2;
					val = val2;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				MimicNetworker.Instance.MimicAttackClientRpc((int)val.playerClientId, mimicIndex);
			}
			else
			{
				interactTrigger.interactable = true;
			}
		}

		public IEnumerator AddAnger(int amount)
		{
			if (angering || attacking)
			{
				yield break;
			}
			angering = true;
			anger += amount;
			if (anger == 1)
			{
				Sprite oldIcon2 = interactTrigger.hoverIcon;
				interactTrigger.hoverIcon = LostFingersIcon;
				mimicAnimator.SetTrigger("Growl");
				yield return (object)new WaitForSeconds(2.75f);
				interactTrigger.hoverIcon = oldIcon2;
				sprayCount = 0;
				angering = false;
				yield break;
			}
			if (anger == 2)
			{
				interactTrigger.holdTip = "DIE : [LMB]";
				interactTrigger.timeToHold = 0.25f;
				Sprite oldIcon2 = interactTrigger.hoverIcon;
				interactTrigger.hoverIcon = LostFingersIcon;
				mimicAnimator.SetTrigger("Growl");
				yield return (object)new WaitForSeconds(2.75f);
				interactTrigger.hoverIcon = oldIcon2;
				sprayCount = 0;
				angering = false;
				yield break;
			}
			if (anger > 2)
			{
				PlayerControllerB val = null;
				float num = 9999f;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val2 in allPlayerScripts)
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = val2;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					MimicNetworker.Instance.MimicAttackClientRpc((int)val.playerClientId, mimicIndex);
				}
			}
			sprayCount = 0;
			angering = false;
		}
	}
	public class MimicCollider : MonoBehaviour, IHittable
	{
		public MimicDoor mimic;

		bool IHittable.Hit(int force, Vector3 hitDirection, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			MimicNetworker.Instance.MimicAddAnger(force, mimic.mimicIndex);
			return true;
		}
	}
	public class MimicListener : MonoBehaviour, INoiseListener
	{
		public MimicDoor mimic;

		private int tolerance = 100;

		void INoiseListener.DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot, int noiseID)
		{
			//IL_0014: 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 ((noiseLoudness >= 0.9f || noiseID == 101158) && Vector3.Distance(noisePosition, ((Component)mimic).transform.position) < 5f)
			{
				switch (noiseID)
				{
				case 75:
					tolerance--;
					break;
				case 5:
					tolerance -= 15;
					break;
				case 101158:
					tolerance -= 35;
					break;
				default:
					tolerance -= 30;
					break;
				}
				if (tolerance <= 0)
				{
					tolerance = 100;
					MimicNetworker.Instance.MimicAddAnger(1, mimic.mimicIndex);
				}
			}
		}
	}
}

mods/x753-More_Suits-1.4.1/BepInEx/plugins/MoreSuits.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MoreSuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds more suit options to Lethal Company")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1")]
[assembly: AssemblyProduct("MoreSuits")]
[assembly: AssemblyTitle("MoreSuits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.1.0")]
[module: UnverifiableCode]
namespace MoreSuits;

[BepInPlugin("x753.More_Suits", "More Suits", "1.4.1")]
public class MoreSuitsMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(ref StartOfRound __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			try
			{
				if (SuitsAdded)
				{
					return;
				}
				int count = __instance.unlockablesList.unlockables.Count;
				UnlockableItem val = new UnlockableItem();
				int num = 0;
				for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val2 = __instance.unlockablesList.unlockables[i];
					if (!((Object)(object)val2.suitMaterial != (Object)null) || !val2.alreadyUnlocked)
					{
						continue;
					}
					val = val2;
					List<string> list = Directory.GetDirectories(Paths.PluginPath, "moresuits", SearchOption.AllDirectories).ToList();
					List<string> list2 = new List<string>();
					List<string> list3 = new List<string>();
					List<string> list4 = DisabledSuits.ToLower().Replace(".png", "").Split(',')
						.ToList();
					List<string> list5 = new List<string>();
					if (!LoadAllSuits)
					{
						foreach (string item2 in list)
						{
							if (File.Exists(Path.Combine(item2, "!less-suits.txt")))
							{
								string[] collection = new string[9] { "glow", "kirby", "knuckles", "luigi", "mario", "minion", "skeleton", "slayer", "smile" };
								list5.AddRange(collection);
								break;
							}
						}
					}
					foreach (string item3 in list)
					{
						if (item3 != "")
						{
							string[] files = Directory.GetFiles(item3, "*.png");
							string[] files2 = Directory.GetFiles(item3, "*.matbundle");
							list2.AddRange(files);
							list3.AddRange(files2);
						}
					}
					list3.Sort();
					list2.Sort();
					try
					{
						foreach (string item4 in list3)
						{
							Object[] array = AssetBundle.LoadFromFile(item4).LoadAllAssets();
							foreach (Object val3 in array)
							{
								if (val3 is Material)
								{
									Material item = (Material)val3;
									customMaterials.Add(item);
								}
							}
						}
					}
					catch (Exception ex)
					{
						Debug.Log((object)("Something went wrong with More Suits! Could not load materials from asset bundle(s). Error: " + ex));
					}
					foreach (string item5 in list2)
					{
						if (list4.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()))
						{
							continue;
						}
						string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
						if (list5.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()) && item5.Contains(directoryName))
						{
							continue;
						}
						UnlockableItem val4;
						Material val5;
						if (Path.GetFileNameWithoutExtension(item5).ToLower() == "default")
						{
							val4 = val;
							val5 = val4.suitMaterial;
						}
						else
						{
							val4 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
							val5 = Object.Instantiate<Material>(val4.suitMaterial);
						}
						byte[] array2 = File.ReadAllBytes(item5);
						Texture2D val6 = new Texture2D(2, 2);
						ImageConversion.LoadImage(val6, array2);
						val5.mainTexture = (Texture)(object)val6;
						val4.unlockableName = Path.GetFileNameWithoutExtension(item5);
						try
						{
							string path = Path.Combine(Path.GetDirectoryName(item5), "advanced", val4.unlockableName + ".json");
							if (File.Exists(path))
							{
								string[] array3 = File.ReadAllLines(path);
								for (int j = 0; j < array3.Length; j++)
								{
									string[] array4 = array3[j].Trim().Split(':');
									if (array4.Length != 2)
									{
										continue;
									}
									string text = array4[0].Trim('"', ' ', ',');
									string text2 = array4[1].Trim('"', ' ', ',');
									if (text2.Contains(".png"))
									{
										byte[] array5 = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(item5), "advanced", text2));
										Texture2D val7 = new Texture2D(2, 2);
										ImageConversion.LoadImage(val7, array5);
										val5.SetTexture(text, (Texture)(object)val7);
										continue;
									}
									if (text == "PRICE" && int.TryParse(text2, out var result))
									{
										try
										{
											val4 = AddToRotatingShop(val4, result, __instance.unlockablesList.unlockables.Count);
										}
										catch (Exception ex2)
										{
											Debug.Log((object)("Something went wrong with More Suits! Could not add a suit to the rotating shop. Error: " + ex2));
										}
										continue;
									}
									switch (text2)
									{
									case "KEYWORD":
										val5.EnableKeyword(text);
										continue;
									case "DISABLEKEYWORD":
										val5.DisableKeyword(text);
										continue;
									case "SHADERPASS":
										val5.SetShaderPassEnabled(text, true);
										continue;
									case "DISABLESHADERPASS":
										val5.SetShaderPassEnabled(text, false);
										continue;
									}
									float result2;
									Vector4 vector;
									if (text == "SHADER")
									{
										Shader shader = Shader.Find(text2);
										val5.shader = shader;
									}
									else if (text == "MATERIAL")
									{
										foreach (Material customMaterial in customMaterials)
										{
											if (((Object)customMaterial).name == text2)
											{
												val5 = Object.Instantiate<Material>(customMaterial);
												val5.mainTexture = (Texture)(object)val6;
												break;
											}
										}
									}
									else if (float.TryParse(text2, out result2))
									{
										val5.SetFloat(text, result2);
									}
									else if (TryParseVector4(text2, out vector))
									{
										val5.SetVector(text, vector);
									}
								}
							}
						}
						catch (Exception ex3)
						{
							Debug.Log((object)("Something went wrong with More Suits! Error: " + ex3));
						}
						val4.suitMaterial = val5;
						if (val4.unlockableName.ToLower() != "default")
						{
							if (num == MaxSuits)
							{
								Debug.Log((object)"Attempted to add a suit, but you've already reached the max number of suits! Modify the config if you want more.");
								continue;
							}
							__instance.unlockablesList.unlockables.Add(val4);
							num++;
						}
					}
					SuitsAdded = true;
					break;
				}
				UnlockableItem val8 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
				val8.alreadyUnlocked = false;
				val8.hasBeenMoved = false;
				val8.placedPosition = Vector3.zero;
				val8.placedRotation = Vector3.zero;
				val8.unlockableType = 753;
				while (__instance.unlockablesList.unlockables.Count < count + MaxSuits)
				{
					__instance.unlockablesList.unlockables.Add(val8);
				}
			}
			catch (Exception ex4)
			{
				Debug.Log((object)("Something went wrong with More Suits! Error: " + ex4));
			}
		}

		[HarmonyPatch("PositionSuitsOnRack")]
		[HarmonyPrefix]
		private static bool PositionSuitsOnRackPatch(ref StartOfRound __instance)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<UnlockableSuit> source = Object.FindObjectsOfType<UnlockableSuit>().ToList();
			source = source.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value).ToList();
			int num = 0;
			foreach (UnlockableSuit item in source)
			{
				AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>();
				component.overrideOffset = true;
				float num2 = 0.18f;
				if (MakeSuitsFitOnRack && source.Count > 13)
				{
					num2 /= (float)Math.Min(source.Count, 20) / 12f;
				}
				component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + __instance.rightmostSuitPosition.forward * num2 * (float)num;
				component.rotationOffset = new Vector3(0f, 90f, 0f);
				num++;
			}
			return false;
		}
	}

	private const string modGUID = "x753.More_Suits";

	private const string modName = "More Suits";

	private const string modVersion = "1.4.1";

	private readonly Harmony harmony = new Harmony("x753.More_Suits");

	private static MoreSuitsMod Instance;

	public static bool SuitsAdded = false;

	public static string DisabledSuits;

	public static bool LoadAllSuits;

	public static bool MakeSuitsFitOnRack;

	public static int MaxSuits;

	public static List<Material> customMaterials = new List<Material>();

	private static TerminalNode cancelPurchase;

	private static TerminalKeyword buyKeyword;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		DisabledSuits = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Disabled Suit List", "UglySuit751.png,UglySuit752.png,UglySuit753.png", "Comma-separated list of suits that shouldn't be loaded").Value;
		LoadAllSuits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Ignore !less-suits.txt", false, "If true, ignores the !less-suits.txt file and will attempt to load every suit, except those in the disabled list. This should be true if you're not worried about having too many suits.").Value;
		MakeSuitsFitOnRack = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Make Suits Fit on Rack", true, "If true, squishes the suits together so more can fit on the rack.").Value;
		MaxSuits = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Suits", 100, "The maximum number of suits to load. If you have more, some will be ignored.").Value;
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin More Suits is loaded!");
	}

	private static UnlockableItem AddToRotatingShop(UnlockableItem newSuit, int price, int unlockableID)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		Terminal val = Object.FindObjectOfType<Terminal>();
		for (int i = 0; i < val.terminalNodes.allKeywords.Length; i++)
		{
			if (((Object)val.terminalNodes.allKeywords[i]).name == "Buy")
			{
				buyKeyword = val.terminalNodes.allKeywords[i];
				break;
			}
		}
		newSuit.alreadyUnlocked = false;
		newSuit.hasBeenMoved = false;
		newSuit.placedPosition = Vector3.zero;
		newSuit.placedRotation = Vector3.zero;
		newSuit.shopSelectionNode = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)newSuit.shopSelectionNode).name = newSuit.unlockableName + "SuitBuy1";
		newSuit.shopSelectionNode.creatureName = newSuit.unlockableName + " suit";
		newSuit.shopSelectionNode.displayText = "You have requested to order " + newSuit.unlockableName + " suits.\nTotal cost of item: [totalCost].\n\nPlease CONFIRM or DENY.\n\n";
		newSuit.shopSelectionNode.clearPreviousText = true;
		newSuit.shopSelectionNode.shipUnlockableID = unlockableID;
		newSuit.shopSelectionNode.itemCost = price;
		newSuit.shopSelectionNode.overrideOptions = true;
		CompatibleNoun val2 = new CompatibleNoun();
		val2.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val2.noun.word = "confirm";
		val2.noun.isVerb = true;
		val2.result = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)val2.result).name = newSuit.unlockableName + "SuitBuyConfirm";
		val2.result.creatureName = "";
		val2.result.displayText = "Ordered " + newSuit.unlockableName + " suits! Your new balance is [playerCredits].\n\n";
		val2.result.clearPreviousText = true;
		val2.result.shipUnlockableID = unlockableID;
		val2.result.buyUnlockable = true;
		val2.result.itemCost = price;
		val2.result.terminalEvent = "";
		CompatibleNoun val3 = new CompatibleNoun();
		val3.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val3.noun.word = "deny";
		val3.noun.isVerb = true;
		if ((Object)(object)cancelPurchase == (Object)null)
		{
			cancelPurchase = ScriptableObject.CreateInstance<TerminalNode>();
		}
		val3.result = cancelPurchase;
		((Object)val3.result).name = "MoreSuitsCancelPurchase";
		val3.result.displayText = "Cancelled order.\n";
		newSuit.shopSelectionNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { val2, val3 };
		TerminalKeyword val4 = ScriptableObject.CreateInstance<TerminalKeyword>();
		((Object)val4).name = newSuit.unlockableName + "Suit";
		val4.word = newSuit.unlockableName.ToLower() + " suit";
		val4.defaultVerb = buyKeyword;
		CompatibleNoun val5 = new CompatibleNoun();
		val5.noun = val4;
		val5.result = newSuit.shopSelectionNode;
		List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList();
		list.Add(val5);
		buyKeyword.compatibleNouns = list.ToArray();
		List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
		list2.Add(val4);
		list2.Add(val2.noun);
		list2.Add(val3.noun);
		val.terminalNodes.allKeywords = list2.ToArray();
		return newSuit;
	}

	public static bool TryParseVector4(string input, out Vector4 vector)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		vector = Vector4.zero;
		string[] array = input.Split(',');
		if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4))
		{
			vector = new Vector4(result, result2, result3, result4);
			return true;
		}
		return false;
	}
}