Decompiled source of LC GiftBox Config v1.1.1

plugins/Xilophor.StaticNetcodeLib.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
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 Microsoft.CodeAnalysis;
using OdinSerializer;
using StaticNetcodeLib.Enums;
using StaticNetcodeLib.Messaging;
using StaticNetcodeLib.Patches;
using StaticNetcodeLib.Serialization;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RegisterFormatterLocator(typeof(INetworkSerializableFormatterLocator), -100)]
[assembly: RegisterFormatter(typeof(NetworkBehaviourReferenceFormatter), 0)]
[assembly: RegisterFormatter(typeof(NetworkObjectReferenceFormatter), 0)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("xilophor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+c96b5d48308fd38bea459d210122948477bffeb9")]
[assembly: AssemblyProduct("StaticNetcodeLib")]
[assembly: AssemblyTitle("Xilophor.StaticNetcodeLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Xilophor/StaticNetcodeLib")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StaticNetcodeLib
{
	[AttributeUsage(AttributeTargets.Class)]
	public class StaticNetcodeAttribute : Attribute
	{
	}
	[BepInPlugin("Xilophor.StaticNetcodeLib", "StaticNetcodeLib", "1.1.1")]
	public class StaticNetcodeLib : BaseUnityPlugin
	{
		public const string Guid = "Xilophor.StaticNetcodeLib";

		private static readonly HarmonyMethod ServerRpcPatch = new HarmonyMethod(typeof(RpcPatcher), "PatchServerRpc", (Type[])null);

		private static readonly HarmonyMethod ClientRpcPatch = new HarmonyMethod(typeof(RpcPatcher), "PatchClientRpc", (Type[])null);

		public static StaticNetcodeLib Instance { get; private set; } = null;


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; private set; }

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Patch();
			GameObject gameObject = ((Component)this).gameObject;
			((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x3D);
			Logger.LogInfo((object)"Xilophor.StaticNetcodeLib v1.1.1 has loaded!");
		}

		private static void Patch()
		{
			//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_0017: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("Xilophor.StaticNetcodeLib");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		private void Start()
		{
			IEnumerable<Type> source = from info in Chainloader.PluginInfos.Values
				where info.Instance != null
				select ((object)info.Instance).GetType() into type
				where ((MemberInfo)type).GetCustomAttributes<BepInDependency>().Any((BepInDependency attr) => attr.DependencyGUID == "Xilophor.StaticNetcodeLib")
				select type;
			Type[] source2 = source.SelectMany((Type plugin) => from type in plugin.Assembly.GetTypes()
				where type.GetCustomAttributes<StaticNetcodeAttribute>().Any()
				select type).ToArray();
			MethodInfo[] source3 = source2.SelectMany((Type type) => type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)).ToArray();
			IEnumerable<MethodInfo> enumerable = source3.Where((MethodInfo method) => ((MemberInfo)method).GetCustomAttributes<ServerRpcAttribute>().Any() && method.IsStatic);
			IEnumerable<MethodInfo> enumerable2 = source3.Where((MethodInfo method) => ((MemberInfo)method).GetCustomAttributes<ClientRpcAttribute>().Any() && method.IsStatic);
			CollectionExtensions.Do<MethodInfo>(enumerable, (Action<MethodInfo>)delegate(MethodInfo method)
			{
				if (!method.Name.EndsWith("ServerRpc"))
				{
					Logger.LogError((object)("Method " + GeneralExtensions.FullDescription((MethodBase)method) + " must end with ServerRpc."));
					return;
				}
				try
				{
					Harmony? harmony2 = Harmony;
					if (harmony2 != null)
					{
						harmony2.Patch((MethodBase)method, ServerRpcPatch, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					RpcPatcher.RpcExecStageLookup[method] = RpcExecStage.None;
				}
				catch
				{
					Logger.LogError((object)("Unable to patch the method " + GeneralExtensions.FullDescription((MethodBase)method) + "!"));
				}
			});
			CollectionExtensions.Do<MethodInfo>(enumerable2, (Action<MethodInfo>)delegate(MethodInfo method)
			{
				if (!method.Name.EndsWith("ClientRpc"))
				{
					Logger.LogError((object)("Method " + GeneralExtensions.FullDescription((MethodBase)method) + " must end with ClientRpc."));
					return;
				}
				try
				{
					Harmony? harmony = Harmony;
					if (harmony != null)
					{
						harmony.Patch((MethodBase)method, ClientRpcPatch, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					RpcPatcher.RpcExecStageLookup[method] = RpcExecStage.None;
				}
				catch
				{
					Logger.LogError((object)("Unable to patch the method " + GeneralExtensions.FullDescription((MethodBase)method) + "!"));
				}
			});
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Xilophor.StaticNetcodeLib";

		public const string PLUGIN_NAME = "StaticNetcodeLib";

		public const string PLUGIN_VERSION = "1.1.1";
	}
}
namespace StaticNetcodeLib.Serialization
{
	public class INetworkSerializableFormatter<T> : MinimalBaseFormatter<T> where T : INetworkSerializable
	{
		private readonly Serializer<byte[]> _byteArraySerializer = Serializer.Get<byte[]>();

		protected override void Read(ref T value, IDataReader reader)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = _byteArraySerializer.ReadValue(reader);
			FastBufferReader val = default(FastBufferReader);
			((FastBufferReader)(ref val))..ctor(array, (Allocator)2, -1, 0);
			BufferSerializer<BufferSerializerReader> val2 = default(BufferSerializer<BufferSerializerReader>);
			val2..ctor(new BufferSerializerReader(val));
			((INetworkSerializable)value).NetworkSerialize<BufferSerializerReader>(val2);
		}

		protected override void Write(ref T value, IDataWriter writer)
		{
			//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)
			//IL_0020: 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)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, 65536);
			BufferSerializer<BufferSerializerWriter> val2 = default(BufferSerializer<BufferSerializerWriter>);
			val2..ctor(new BufferSerializerWriter(val));
			((INetworkSerializable)value).NetworkSerialize<BufferSerializerWriter>(val2);
			Serializer<byte[]> byteArraySerializer = _byteArraySerializer;
			FastBufferWriter fastBufferWriter = val2.GetFastBufferWriter();
			byteArraySerializer.WriteValue(((FastBufferWriter)(ref fastBufferWriter)).ToArray(), writer);
		}
	}
	public class INetworkSerializableFormatterLocator : IFormatterLocator
	{
		public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, bool allowWeakFallbackFormatters, out IFormatter formatter)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if ((int)step != 1 || !typeof(INetworkSerializable).IsAssignableFrom(type))
			{
				formatter = null;
				return false;
			}
			try
			{
				formatter = (IFormatter)Activator.CreateInstance(typeof(INetworkSerializableFormatter<>).MakeGenericType(type));
			}
			catch (Exception ex)
			{
				if (!allowWeakFallbackFormatters || (!(ex is ExecutionEngineException) && !(ex.GetBaseException() is ExecutionEngineException)))
				{
					throw;
				}
				formatter = (IFormatter)new WeakSerializableFormatter(type);
			}
			return true;
		}
	}
	public class NetworkBehaviourReferenceFormatter : MinimalBaseFormatter<NetworkBehaviourReference>
	{
		private static readonly Serializer<ushort> UInt16Serializer = Serializer.Get<ushort>();

		private static readonly Serializer<NetworkObjectReference> NetworkObjectReferenceSerializer = Serializer.Get<NetworkObjectReference>();

		protected override void Read(ref NetworkBehaviourReference value, IDataReader reader)
		{
			//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)
			value.m_NetworkObjectReference = NetworkObjectReferenceSerializer.ReadValue(reader);
			value.m_NetworkBehaviourId = UInt16Serializer.ReadValue(reader);
		}

		protected override void Write(ref NetworkBehaviourReference value, IDataWriter writer)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			NetworkObjectReferenceSerializer.WriteValue(value.m_NetworkObjectReference, writer);
			UInt16Serializer.WriteValue(value.m_NetworkBehaviourId, writer);
		}
	}
	internal class NetworkObjectReferenceFormatter : MinimalBaseFormatter<NetworkObjectReference>
	{
		private static readonly Serializer<ulong> UInt64Serializer = Serializer.Get<ulong>();

		protected override void Read(ref NetworkObjectReference value, IDataReader reader)
		{
			((NetworkObjectReference)(ref value)).NetworkObjectId = UInt64Serializer.ReadValue(reader);
		}

		protected override void Write(ref NetworkObjectReference value, IDataWriter writer)
		{
			UInt64Serializer.WriteValue(((NetworkObjectReference)(ref value)).NetworkObjectId, writer);
		}
	}
}
namespace StaticNetcodeLib.Patches
{
	[HarmonyPatch(typeof(NetworkManager))]
	[HarmonyPriority(500)]
	[HarmonyWrapSafe]
	internal static class NetworkManagerPatch
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		public static void InitializePatch()
		{
			new UnnamedMessageHandler();
		}

		[HarmonyPatch("Shutdown")]
		[HarmonyPrefix]
		public static void ShutdownPatch()
		{
			UnnamedMessageHandler.Instance?.Dispose();
		}
	}
	internal class RpcPatcher
	{
		internal static Dictionary<MethodBase, RpcExecStage> RpcExecStageLookup { get; } = new Dictionary<MethodBase, RpcExecStage>();


		public static bool PatchServerRpc(MethodBase __originalMethod, object[] __args)
		{
			if (!IsListening(out NetworkManager networkManager))
			{
				return false;
			}
			RpcExecStage rpcExecStage = RpcExecStageLookup[__originalMethod];
			if (rpcExecStage == RpcExecStage.Server)
			{
				return true;
			}
			if (!networkManager.IsClient && !networkManager.IsHost)
			{
				return false;
			}
			SendServerRpc(__originalMethod, ref __args);
			return false;
		}

		public static bool PatchClientRpc(MethodBase __originalMethod, object[]? __args)
		{
			if (!IsListening(out NetworkManager networkManager))
			{
				return false;
			}
			RpcExecStage rpcExecStage = RpcExecStageLookup[__originalMethod];
			if (rpcExecStage == RpcExecStage.Client)
			{
				return true;
			}
			if (!networkManager.IsHost && !networkManager.IsServer)
			{
				return false;
			}
			SendClientRpc(__originalMethod, __args);
			return false;
		}

		private static bool IsListening(out NetworkManager? networkManager)
		{
			networkManager = NetworkManager.Singleton;
			if ((Object)(object)networkManager != (Object)null && networkManager.IsListening)
			{
				return UnnamedMessageHandler.Instance != null;
			}
			return false;
		}

		private static void SendServerRpc(MethodBase __originalMethod, ref object[] __args)
		{
			//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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!IsListening(out NetworkManager networkManager))
			{
				return;
			}
			MessageData messageData = new MessageData(MessageType.ServerRpc, __originalMethod, __args);
			for (int num = __args.Length - 1; num >= 0; num--)
			{
				if (__args[num] is ServerRpcParams val)
				{
					val.Receive.SenderClientId = networkManager.LocalClientId;
					__args[num] = val;
					break;
				}
			}
			UnnamedMessageHandler.Instance.SendMessageToServer(messageData);
		}

		private static void SendClientRpc(MethodBase __originalMethod, object[]? __args)
		{
			//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_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)
			if (!IsListening(out NetworkManager _))
			{
				return;
			}
			MessageData messageData = new MessageData(MessageType.ClientRpc, __originalMethod, __args);
			if (__args == null || __args.Length == 0 || !__args.Any((object arg) => arg is ClientRpcParams))
			{
				UnnamedMessageHandler.Instance.SendMessageToClient(messageData);
				return;
			}
			ClientRpcParams clientRpcParams = (ClientRpcParams)__args.FirstOrDefault((object arg) => arg is ClientRpcParams);
			UnnamedMessageHandler.Instance.SendMessageToClient(messageData, clientRpcParams);
		}
	}
}
namespace StaticNetcodeLib.Messaging
{
	public record MessageData([property: OdinSerialize] MessageType MessageType, [property: OdinSerialize] MethodBase MethodBase, [property: OdinSerialize] object? Data)
	{
		public (MessageType, MethodBase, object?) AsValueTuple()
		{
			return (MessageType, MethodBase, Data);
		}
	}
	internal class UnnamedMessageHandler : IDisposable
	{
		private const string LibIdentifier = "StaticNetcodeLib";

		private static readonly SerializationContext DefaultSerializationContext = new SerializationContext
		{
			Config = new SerializationConfig
			{
				SerializationPolicy = SerializationPolicies.Everything
			}
		};

		private static readonly DeserializationContext DefaultDeserializationContext = new DeserializationContext
		{
			Config = new SerializationConfig
			{
				SerializationPolicy = SerializationPolicies.Everything
			}
		};

		internal static UnnamedMessageHandler? Instance { get; private set; }

		private NetworkManager NetworkManager { get; }

		private CustomMessagingManager CustomMessagingManager { get; }

		internal UnnamedMessageHandler()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			Instance = this;
			NetworkManager = NetworkManager.Singleton;
			CustomMessagingManager = NetworkManager.CustomMessagingManager;
			CustomMessagingManager.OnUnnamedMessage += new UnnamedMessageDelegate(ReceiveMessage);
		}

		internal void SendMessageToClient(MessageData messageData, ClientRpcParams clientRpcParams = default(ClientRpcParams))
		{
			//IL_0008: 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)
			//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_00ea: 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_0085: 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)
			WriteMessageData(out var writer, messageData);
			IReadOnlyList<ulong> readOnlyList = clientRpcParams.Send.TargetClientIds ?? clientRpcParams.Send.TargetClientIdsNativeArray.GetValueOrDefault().ToArray();
			if (readOnlyList.Any((ulong client) => client == 0))
			{
				readOnlyList = readOnlyList.Where((ulong client) => client != 0) as IReadOnlyList<ulong>;
				FastBufferReader message = default(FastBufferReader);
				((FastBufferReader)(ref message))..ctor(writer, (Allocator)2, -1, 0, (Allocator)2);
				try
				{
					ReceiveMessage(0uL, message);
					if ((readOnlyList == null || readOnlyList.Count == 0) ? true : false)
					{
						((FastBufferWriter)(ref writer)).Dispose();
						return;
					}
				}
				finally
				{
					((IDisposable)(FastBufferReader)(ref message)).Dispose();
				}
			}
			if (readOnlyList.Any())
			{
				CustomMessagingManager.SendUnnamedMessage(readOnlyList, writer, (NetworkDelivery)4);
			}
			else
			{
				CustomMessagingManager.SendUnnamedMessageToAll(writer, (NetworkDelivery)4);
			}
			((FastBufferWriter)(ref writer)).Dispose();
		}

		internal void SendMessageToServer(MessageData messageData)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			WriteMessageData(out var writer, messageData);
			CustomMessagingManager.SendUnnamedMessage(0uL, writer, (NetworkDelivery)4);
			((FastBufferWriter)(ref writer)).Dispose();
		}

		private void ReceiveMessage(ulong clientId, FastBufferReader message)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			string text = default(string);
			((FastBufferReader)(ref message)).ReadValueSafe(ref text, false);
			if (!(text != "StaticNetcodeLib"))
			{
				byte[] serializedData = default(byte[]);
				((FastBufferReader)(ref message)).ReadValueSafe<byte>(ref serializedData, default(ForPrimitives));
				MessageData messageData = DeserializeMessageData(serializedData);
				switch (messageData.MessageType)
				{
				case MessageType.ServerRpc:
				case MessageType.ClientRpc:
					ReceiveRpc(messageData);
					break;
				case MessageType.Variable:
					throw new NotImplementedException();
				default:
					throw new ArgumentOutOfRangeException();
				}
			}
		}

		private void ReceiveRpc(MessageData messageData)
		{
			(MessageType, MethodBase, object?) tuple = messageData.AsValueTuple();
			MethodBase item = tuple.Item2;
			object item2 = tuple.Item3;
			item = item ?? throw new NullReferenceException("MethodBase is null.");
			object[] array = (object[])item2;
			object[] parameters = ((array != null && array.Length == 0) ? null : ((object[])item2));
			RpcExecStage value = ((messageData.MessageType == MessageType.ServerRpc) ? RpcExecStage.Server : RpcExecStage.Client);
			RpcPatcher.RpcExecStageLookup[item] = value;
			item.Invoke(null, parameters);
			RpcPatcher.RpcExecStageLookup[item] = RpcExecStage.None;
		}

		private static byte[] Serialize(object? data)
		{
			return SerializationUtility.SerializeValue<object>(data, (DataFormat)0, DefaultSerializationContext);
		}

		private static byte[] SerializeMessageData(MessageData messageData)
		{
			return SerializationUtility.SerializeValue<MessageData>(messageData with
			{
				Data = Serialize(messageData.Data)
			}, (DataFormat)0, (SerializationContext)null);
		}

		private static T Deserialize<T>(byte[] serializedData)
		{
			return SerializationUtility.DeserializeValue<T>(serializedData, (DataFormat)0, DefaultDeserializationContext);
		}

		private static MessageData DeserializeMessageData(byte[] serializedData)
		{
			MessageData messageData = SerializationUtility.DeserializeValue<MessageData>(serializedData, (DataFormat)0, (DeserializationContext)null);
			return messageData with
			{
				Data = Deserialize<object[]>((byte[])messageData.Data)
			};
		}

		private static void WriteMessageData(out FastBufferWriter writer, MessageData messageData)
		{
			//IL_0017: 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_0031: 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)
			(byte[], int) tuple = SerializeDataAndGetSize(messageData);
			byte[] item = tuple.Item1;
			int item2 = tuple.Item2;
			writer = new FastBufferWriter(item2, (Allocator)2, -1);
			((FastBufferWriter)(ref writer)).WriteValueSafe("StaticNetcodeLib", false);
			((FastBufferWriter)(ref writer)).WriteValueSafe<byte>(item, default(ForPrimitives));
		}

		private static (byte[], int) SerializeDataAndGetSize(MessageData messageData)
		{
			int num = 0;
			byte[] array = SerializeMessageData(messageData);
			num += Encoding.UTF8.GetByteCount("StaticNetcodeLib");
			num += array.Length;
			num += 100;
			return (array, num);
		}

		public void Dispose()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			CustomMessagingManager.OnUnnamedMessage -= new UnnamedMessageDelegate(ReceiveMessage);
		}
	}
}
namespace StaticNetcodeLib.Enums
{
	public enum MessageType
	{
		ServerRpc,
		ClientRpc,
		Variable
	}
	internal enum RpcExecStage
	{
		None,
		Server,
		Client
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	internal static class IsExternalInit
	{
	}
}

plugins/LC_GiftBox_Config.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LC_GiftBox_Config.libs.HarmonyXExtensions;
using LC_GiftBox_Config.libs.ILStepper;
using LC_GiftBox_Config.libs.LethalConfigNicerizer;
using LC_GiftBox_Config.libs.Probability;
using LethalConfig;
using LethalConfig.ConfigItems;
using Microsoft.CodeAnalysis;
using StaticNetcodeLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("DBJ")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Configure gift boxes / presents, such as having store items / scrap / another present / nothing, weighting of item selection, spawn rates, etc.")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+704f2e95fca5e8ab734e8c24eac0aa86477ce5d3")]
[assembly: AssemblyProduct("LC_GiftBox_Config")]
[assembly: AssemblyTitle("com.github.decibillyjoel.lc_giftbox_config")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/DecibillyJoel/LC_GiftBox_Config")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "com.github.decibillyjoel.lc_giftbox_config";

	public const string PLUGIN_NAME = "LC_GiftBox_Config";

	public const string PLUGIN_TS_TEAM = "DBJ";

	public const string PLUGIN_VERSION = "1.1.1";
}
namespace LC_GiftBox_Config
{
	[BepInPlugin("com.github.decibillyjoel.lc_giftbox_config", "DBJ.LC_GiftBox_Config", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource PluginLogger = null;

		public static ConfigEntry<bool> giftboxMechanicsDisabled = null;

		public static ConfigEntry<bool> giftboxDupeSoundsBugFixDisabled = null;

		public static ConfigEntry<bool> giftboxToolScrapValueBugfixDisabled = null;

		public static ConfigEntry<int> giftboxEggsplosionChance = null;

		public static ConfigEntry<int> spawnStoreItemChance = null;

		public static ConfigEntry<int> spawnScrapChance = null;

		public static ConfigEntry<int> spawnGiftBoxChance = null;

		public static ConfigEntry<int> spawnNothingChance = null;

		public static ConfigEntry<int> doNothingChance = null;

		public static ConfigEntry<int> scrapValueMin = null;

		public static ConfigEntry<int> scrapValueMax = null;

		public static ConfigEntry<int> scrapValueInfluence = null;

		public static ConfigEntry<int> scrapRarityMin = null;

		public static ConfigEntry<int> scrapRarityMax = null;

		public static ConfigEntry<int> scrapRarityInfluence = null;

		public static ConfigEntry<int> scrapValueIsGiftBoxChance = null;

		public static ConfigEntry<int> scrapValueAdditionChance = null;

		public static ConfigEntry<int> scrapValueAdditionMin = null;

		public static ConfigEntry<int> scrapValueAdditionMax = null;

		public static ConfigEntry<int> scrapValueMultiplierChance = null;

		public static ConfigEntry<int> scrapValueMultiplierMin = null;

		public static ConfigEntry<int> scrapValueMultiplierMax = null;

		public static ConfigEntry<int> giftboxValueAdditionChance = null;

		public static ConfigEntry<int> giftboxValueAdditionMin = null;

		public static ConfigEntry<int> giftboxValueAdditionMax = null;

		public static ConfigEntry<int> giftboxValueMultiplierChance = null;

		public static ConfigEntry<int> giftboxValueMultiplierMin = null;

		public static ConfigEntry<int> giftboxValueMultiplierMax = null;

		public static ConfigEntry<int> giftboxRarityAdditionChance = null;

		public static ConfigEntry<int> giftboxRarityAdditionMin = null;

		public static ConfigEntry<int> giftboxRarityAdditionMax = null;

		public static ConfigEntry<int> giftboxRarityMultiplierChance = null;

		public static ConfigEntry<int> giftboxRarityMultiplierMin = null;

		public static ConfigEntry<int> giftboxRarityMultiplierMax = null;

		public static ConfigEntry<int> giftboxSpawnChance = null;

		public static ConfigEntry<int> giftboxSpawnMin = null;

		public static ConfigEntry<int> giftboxSpawnMax = null;

		public static ConfigEntry<int> storeItemPriceMin = null;

		public static ConfigEntry<int> storeItemPriceMax = null;

		public static ConfigEntry<int> storeItemPriceInfluence = null;

		internal static readonly Harmony harmony = new Harmony("DBJ.LC_GiftBox_Config");

		public static void Log(LogLevel logLevel, string logMessage)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			PluginLogger.Log(logLevel, (object)(logMessage ?? ""));
		}

		public static void Log(string logMessage)
		{
			Log((LogLevel)16, logMessage);
		}

		private void ValidateMinMaxOrder(ConfigEntry<int> minEntry, ConfigEntry<int> maxEntry)
		{
			if (minEntry.Value > maxEntry.Value)
			{
				Log((LogLevel)4, "|" + ((ConfigEntryBase)minEntry).Definition.Key + "| is greater than |" + ((ConfigEntryBase)maxEntry).Definition.Key + "! Swapping values...");
				int value = maxEntry.Value;
				int value2 = minEntry.Value;
				minEntry.Value = value;
				maxEntry.Value = value2;
			}
		}

		private void ValidateConfigAndApplyPatches()
		{
			Log((LogLevel)32, "Validating config...");
			((BaseUnityPlugin)this).Config.SettingChanged -= ScheduleValidateConfigAndApplyPatches;
			if (spawnStoreItemChance.Value == 0 && spawnScrapChance.Value == 0 && spawnGiftBoxChance.Value == 0 && spawnNothingChance.Value == 0 && doNothingChance.Value == 0)
			{
				int maxValue = (((ConfigEntryBase)doNothingChance).Description.AcceptableValues as AcceptableValueRange<int>).MaxValue;
				Log((LogLevel)2, $"All [{((ConfigEntryBase)doNothingChance).Definition.Section}] config weights are 0! Setting |{((ConfigEntryBase)doNothingChance).Definition.Key}| to {maxValue}...");
				doNothingChance.Value = maxValue;
			}
			ValidateMinMaxOrder(scrapValueMin, scrapValueMax);
			ValidateMinMaxOrder(scrapRarityMin, scrapRarityMax);
			ValidateMinMaxOrder(scrapValueAdditionMin, scrapValueAdditionMax);
			ValidateMinMaxOrder(scrapValueMultiplierMin, scrapValueMultiplierMax);
			ValidateMinMaxOrder(storeItemPriceMin, storeItemPriceMax);
			ValidateMinMaxOrder(giftboxRarityAdditionMin, giftboxRarityAdditionMax);
			ValidateMinMaxOrder(giftboxRarityMultiplierMin, giftboxRarityMultiplierMax);
			ValidateMinMaxOrder(giftboxValueAdditionMin, giftboxValueAdditionMax);
			ValidateMinMaxOrder(giftboxValueMultiplierMin, giftboxValueMultiplierMax);
			ValidateMinMaxOrder(giftboxSpawnMin, giftboxSpawnMax);
			((BaseUnityPlugin)this).Config.SettingChanged += ScheduleValidateConfigAndApplyPatches;
			Log((LogLevel)32, "Unpatching...");
			harmony.UnpatchSelf();
			Log((LogLevel)32, "Patching...");
			harmony.PatchAll();
			Log((LogLevel)32, "Finished config validation and patching!");
		}

		private void ScheduleValidateConfigAndApplyPatches(object? eventSender = null, SettingChangedEventArgs? eventArgs = null)
		{
			Log((LogLevel)32, "Scheduling config validation...");
			string text = "ValidateConfigAndApplyPatches";
			((MonoBehaviour)this).CancelInvoke(text);
			((MonoBehaviour)this).Invoke(text, 0.33f);
		}

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Expected O, but got Unknown
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Expected O, but got Unknown
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Expected O, but got Unknown
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Expected O, but got Unknown
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Expected O, but got Unknown
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Expected O, but got Unknown
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Expected O, but got Unknown
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Expected O, but got Unknown
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Expected O, but got Unknown
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Expected O, but got Unknown
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Expected O, but got Unknown
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Expected O, but got Unknown
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Expected O, but got Unknown
			//IL_066b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0675: Expected O, but got Unknown
			//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ae: Expected O, but got Unknown
			//IL_06e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ee: Expected O, but got Unknown
			//IL_0724: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Expected O, but got Unknown
			//IL_075d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0767: Expected O, but got Unknown
			//IL_0799: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a3: Expected O, but got Unknown
			//IL_07d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e2: Expected O, but got Unknown
			//IL_0811: Unknown result type (might be due to invalid IL or missing references)
			//IL_081b: Expected O, but got Unknown
			//IL_0849: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Expected O, but got Unknown
			//IL_0881: Unknown result type (might be due to invalid IL or missing references)
			//IL_088b: Expected O, but got Unknown
			//IL_08ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c4: Expected O, but got Unknown
			//IL_08eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f5: Expected O, but got Unknown
			//IL_091c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0926: Expected O, but got Unknown
			//IL_094d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0957: Expected O, but got Unknown
			PluginLogger = ((BaseUnityPlugin)this).Logger;
			Log("[v1.1.1] Loading...");
			spawnStoreItemChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Item Type", "Store Item Chance (Selection Weight)", 50, new ConfigDescription("The selection weight of a gift box containing a store item.     \n0 = will not happen    \nLarger selection weight = more likely to happen    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			spawnScrapChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Item Type", "Scrap Item Chance (Selection Weight)", 30, new ConfigDescription("The selection weight of a gift box containing a scrap item.     \n0 = will not happen    \nLarger selection weight = more likely to happen    \n    \n[Vanilla Value: 100]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			spawnGiftBoxChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Item Type", "Gift Box Chance (Selection Weight)", 5, new ConfigDescription("The selection weight of a gift box containing another gift box.     \n0 = will not happen    \nLarger selection weight = more likely to happen    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			spawnNothingChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Item Type", "Empty Chance (Selection Weight)", 15, new ConfigDescription("The selection weight of a gift box being empty.     \n0 = will not happen    \nLarger selection weight = more likely to happen    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			doNothingChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Item Type", "Unmodified Chance (Selection Weight)", 0, new ConfigDescription("The selection weight of a gift box not being modified by this mod, i.e. so another gift box mod's effects can function instead.     \n0 = will not happen    \nLarger selection weight = more likely to happen    \n    \nIf you do not have any other gift box mods that function by transpiling OpenGiftBoxServerRpc(), I recommend leaving this value at 0. Otherwise, I recommend setting their probability values to 100% and this probability value to the weight you'd like to assign to the other mod, so that whenever this mod selects this hands-off behavior, the other mod's functionality will have a 100% chance to occur rather than simply using vanilla behavior", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			scrapValueMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Scrap Value Minimum", 0, new ConfigDescription("The minimum value required for a scrap item to be selected by the gift box    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			scrapValueMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Scrap Value Maximum", int.MaxValue, new ConfigDescription("The maximum value required for a scrap item to be selected by the gift box    \n    \n[Vanilla Value: infinity]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			scrapValueInfluence = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Scrap Value Influence (%)", -50, new ConfigDescription("How much influence a scrap item's value has over its selection weight.     \n0 = scrap item's value does not influence its selection weight    \nLarger influence percentage = high-value scrap items are more likely than low-value scrap items    \nNegative influence percentage = high-value scrap items are less likely than low-value scrap items    \n    \nEach selectable scrap item is given a selection weight equal to their scrap value raised to the power of this percentage (i.e. 100% = 100 / 10    \n0 = 1, so the exponent is 1). e.g. if this percentage is set to 200%, a scrap item with a value of 2 has a selection weight of 4 (2 ^ 200% = 2 ^ 2 = 4), which is four times the selection weight of a scrap item with a value of 1 and therefore a selection weight of 1 (1 ^ 200% = 1 ^ 2 = 1). If this value is negative, then the selection weights are inverted - e.g. -100% results in a scrap item with a value of 2 receiving a selection weight of 0.5 (2 ^ -100% = 2 ^ -1 = 1 / (2 ^ 1) = 1 / 2 = 0.5)    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			scrapRarityMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Spawn Weight Minimum", 0, new ConfigDescription("The minimum spawn weight required for a scrap item to be selected by the gift box    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			scrapRarityMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Spawn Weight Maximum", int.MaxValue, new ConfigDescription("The maximum value required for a scrap item to be selected by the gift box    \n    \n[Vanilla Value: infinity]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			scrapRarityInfluence = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Item", "Spawn Weight Influence (%)", 50, new ConfigDescription("How much influence a scrap item's spawn weight within the current level has over its selection weight.     \n0 = scrap item's spawn weight does not influence its selection weight    \nLarger influence percentage = common scrap items are more likely than rare scrap items    \nNegative influence percentage = common scrap items are less likely than rare scrap items    \n    \nEach selectable scrap item is given a selection weight equal to their spawn weight raised to the power of this percentage (i.e. 100% = 100 / 10    \n0 = 1, so the exponent is 1). e.g. if this percentage is set to 200%, a scrap item with a spawn weight of 2 has a selection weight of 4 (2 ^ 200% = 2 ^ 2 = 4), which is four times the selection weight of a scrap item with a spawn weight of 1 and therefore a selection weight of 1 (1 ^ 200% = 1 ^ 2 = 1). If this value is negative, then the selection weights are inverted - e.g. -100% results in a scrap item with a spawn weight of 2 receiving a selection weight of 0.5 (2 ^ -100% = 2 ^ -1 = 1 / (2 ^ 1) = 1 / 2 = 0.5)    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			storeItemPriceMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Store Item", "Price Minimum", 0, new ConfigDescription("The minimum store item price required for an item to be selected by the gift box    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			storeItemPriceMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Store Item", "Price Maximum", int.MaxValue, new ConfigDescription("The maximum store item price required for an item to be selected by the gift box    \n    \n[Vanilla Value: infinity]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>())));
			storeItemPriceInfluence = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Store Item", "Price Influence (%)", -100, new ConfigDescription("How much influence a store item's price has over its selection weight.     \n0 = store item's price does not influence its selection weight    \nLarger influence percentage = expensive store items are more likely than cheap store items    \nNegative influence percentage = expensive store items are less likely than cheap store items    \n    \nEach selectable store item is given a selection weight equal to their store price raised to the power of this percentage (i.e. 100% = 100 / 10    \n0 = 1, so the exponent is 1). e.g. if this percentage is set to 200%, a store item with a price of 2 has a selection weight of 4 (2 ^ 200% = 2 ^ 2 = 4), which is four times the selection weight of a store item with a price of 1 and therefore a selection weight of 1 (1 ^ 200% = 1 ^ 2 = 1). If this value is negative, then the selection weights are inverted - e.g. -100% results in a store item with a price of 2 receiving a selection weight of 0.5 (2 ^ -100% = 2 ^ -1 = 1 / (2 ^ 1) = 1 / 2 = 0.5)    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			scrapValueIsGiftBoxChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Inherit Gift Box Value Chance (%)", 15, new ConfigDescription("The likelihood (% chance) of the selected scrap item having the same scrap value as the gift box itself    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			scrapValueAdditionChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Addition Chance (%)", 100, new ConfigDescription("The likelihood (% chance) of the selected scrap item receiving an addition to its scrap value (if the scrap item inherits the gift box's scrap value, this addition will not be applied)    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			scrapValueAdditionMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Addition Minimum", 30, new ConfigDescription("The minimum possible value of the addition applied to the selected scrap item's scrap value    \n    \n[Vanilla Value: 25]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			scrapValueAdditionMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Addition Maximum", 40, new ConfigDescription("The maximum possible value of the addition applied to the selected scrap item's scrap value    \n    \n[Vanilla Value: 35]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			scrapValueMultiplierChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Multiplier Chance (%)", 35, new ConfigDescription("The likelihood (% chance) of the selected scrap item receiving a multiplier to its scrap value (if the scrap item inherits the gift box's scrap value, this multiplier will not be applied)    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			scrapValueMultiplierMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Multiplier Minimum (%)", 120, new ConfigDescription("The minimum possible value of the multiplier applied to the selected scrap item's scrap value    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			scrapValueMultiplierMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Contained Scrap Value", "Multiplier Maximum (%)", 150, new ConfigDescription("The maximum possible value of the multiplier applied to the selected scrap item's scrap value    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			giftboxValueAdditionChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Addition Chance (%)", 100, new ConfigDescription("The likelihood (% chance) of the gift box receiving an addition to its scrap value    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxValueAdditionMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Addition Minimum", 30, new ConfigDescription("The minimum possible value of the addition applied to the gift box's scrap value    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			giftboxValueAdditionMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Addition Maximum", 40, new ConfigDescription("The maximum possible value of the addition applied to the gift box's scrap value    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			giftboxValueMultiplierChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Multiplier Chance (%)", 35, new ConfigDescription("The likelihood (% chance) of the gift box receiving a multiplier to its scrap value    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxValueMultiplierMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Multiplier Minimum (%)", 120, new ConfigDescription("The minimum possible value of the multiplier applied to the gift box's scrap value    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			giftboxValueMultiplierMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Scrap Value", "Multiplier Maximum (%)", 150, new ConfigDescription("The maximum possible value of the multiplier applied to the gift box's scrap value    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			giftboxRarityAdditionChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Addition Chance (%)", 25, new ConfigDescription("The likelihood (% chance) of gift boxes receiving an addition to their spawn weight within the current level    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxRarityAdditionMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Addition Minimum", 10, new ConfigDescription("The minimum possible value of the addition applied to gift boxes' spawn weight within the current level    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			giftboxRarityAdditionMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Addition Maximum", 15, new ConfigDescription("The maximum possible value of the addition applied to gift boxes' spawn weight within the current level    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())));
			giftboxRarityMultiplierChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Multiplier Chance (%)", 25, new ConfigDescription("The likelihood (% chance) of gift boxes receiving a multiplier to their spawn weight within the current level    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxRarityMultiplierMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Multiplier Minimum", 120, new ConfigDescription("The minimum possible value of the multiplier applied to gift boxes' spawn weight within the current level    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			giftboxRarityMultiplierMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Weight", "Multiplier Maximum", 150, new ConfigDescription("The maximum possible value of the multiplier applied to gift boxes' spawn weight within the current level    \n    \n[Vanilla Value: 100%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())));
			giftboxSpawnChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Anomaly", "Anomalous Spawning Chance (%)", 65, new ConfigDescription("The likelihood (% chance) of gift boxes anomalously spawning in the current level, separate from the level's natural scrap pool mechanics    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxSpawnMin = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Anomaly", "Minimum Gift Boxes", 2, new ConfigDescription("The minimum possible number of gift boxes to be anomalously spawned    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxSpawnMax = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Spawn Anomaly", "Maximum Gift Boxes", 5, new ConfigDescription("The maximum possible number of gift boxes to be anomalously spawned    \n    \n[Vanilla Value: 0]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxEggsplosionChance = LethalConfigNicerizer.Nicerize<int>(((BaseUnityPlugin)this).Config.Bind<int>("Gift Box Behaviors", "Empty Gift Box Eggsplosion Chance (%)", 100, new ConfigDescription("The likelihood (% chance) of an empty gift box non-harmfully eggsploding (it won't harm you, but it may attract enemies who will)    \n    \n[Vanilla Value: 0%]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			giftboxMechanicsDisabled = LethalConfigNicerizer.Nicerize<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility / Debugging", "Disable All Mod Mechanics", false, new ConfigDescription("WARNING: May cause unexpected game behaviors, desyncs, or loss / corruption of mod-related save data! Do not use this setting unless you know what you're doing!    \n    \nToggle this setting to disable the modded gift box mechanics", (AcceptableValueBase)null, Array.Empty<object>())));
			giftboxDupeSoundsBugFixDisabled = LethalConfigNicerizer.Nicerize<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility / Debugging", "Disable Gift Box Duplicate Sounds Bugfix", false, new ConfigDescription("Toggle this setting to disable the gift box duplicate sounds bugfix", (AcceptableValueBase)null, Array.Empty<object>())));
			giftboxToolScrapValueBugfixDisabled = LethalConfigNicerizer.Nicerize<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility / Debugging", "Disable Gift Box Setting Tool Scrap Value Bugfix", false, new ConfigDescription("Toggle this setting to disable the bugfix for the gift box setting a tool's scrap value", (AcceptableValueBase)null, Array.Empty<object>())));
			MigrateOldEntries(("Gift Box - Gift Box Value", "Chance for the gift box to receive scrap value addition (%)", (ConfigEntryBase)(object)giftboxValueAdditionChance), ("Gift Box - Gift Box Value", "Minimum gift box value addition", (ConfigEntryBase)(object)giftboxValueAdditionMin), ("Gift Box - Gift Box Value", "Maximum gift box value addition", (ConfigEntryBase)(object)giftboxValueAdditionMax), ("Gift Box - Gift Box Value", "Chance for gift box to receive scrap value multiplier (%)", (ConfigEntryBase)(object)giftboxValueMultiplierChance), ("Gift Box - Gift Box Value", "Minimum gift box value multiplier (%)", (ConfigEntryBase)(object)giftboxValueMultiplierMin), ("Gift Box - Gift Box Value", "Maximum gift box value multiplier (%)", (ConfigEntryBase)(object)giftboxValueMultiplierMax), ("Gift Box - Gift Box Natural Spawn Chance", "Chance for gift boxes to receive spawn weight addition (%)", (ConfigEntryBase)(object)giftboxRarityAdditionChance), ("Gift Box - Gift Box Natural Spawn Chance", "Minimum gift box spawn weight addition", (ConfigEntryBase)(object)giftboxRarityAdditionMin), ("Gift Box - Gift Box Natural Spawn Chance", "Maximum gift box spawn weight addition", (ConfigEntryBase)(object)giftboxRarityAdditionMax), ("Gift Box - Gift Box Natural Spawn Chance", "Chance for gift boxes to receive spawn weight multiplier (%)", (ConfigEntryBase)(object)giftboxRarityMultiplierChance), ("Gift Box - Gift Box Natural Spawn Chance", "Minimum gift box spawn weight multiplier (%)", (ConfigEntryBase)(object)giftboxRarityMultiplierMin), ("Gift Box - Gift Box Natural Spawn Chance", "Maximum gift box spawn weight multiplier (%)", (ConfigEntryBase)(object)giftboxRarityMultiplierMax), ("Gift Box - Gift Box Anomalous Spawning", "Chance for gift boxes to anomalously spawn (%)", (ConfigEntryBase)(object)giftboxSpawnChance), ("Gift Box - Gift Box Anomalous Spawning", "Minimum number of anomalously spawned gift boxes", (ConfigEntryBase)(object)giftboxSpawnMin), ("Gift Box - Gift Box Anomalous Spawning", "Maximum number of anomalously spawned gift boxes", (ConfigEntryBase)(object)giftboxSpawnMax), ("Gift Box - Behavior Selection", "Chance to select a store item (Selection Weight)", (ConfigEntryBase)(object)spawnStoreItemChance), ("Gift Box - Behavior Selection", "Chance to select a scrap item (Selection Weight)", (ConfigEntryBase)(object)spawnScrapChance), ("Gift Box - Behavior Selection", "Chance to select another gift box (Selection Weight)", (ConfigEntryBase)(object)spawnGiftBoxChance), ("Gift Box - Behavior Selection", "Chance to select no item (Selection Weight)", (ConfigEntryBase)(object)spawnNothingChance), ("Gift Box - Behavior Selection", "Chance to leave gift box unmodified (Selection Weight)", (ConfigEntryBase)(object)doNothingChance), ("Gift Box - Scrap Selection", "Minimum selectable scrap value", (ConfigEntryBase)(object)scrapValueMin), ("Gift Box - Scrap Selection", "Maximum selectable scrap value", (ConfigEntryBase)(object)scrapValueMax), ("Gift Box - Scrap Selection", "Scrap value influence percentage (%)", (ConfigEntryBase)(object)scrapValueInfluence), ("Gift Box - Scrap Selection", "Minimum selectable scrap spawn weight", (ConfigEntryBase)(object)scrapRarityMin), ("Gift Box - Scrap Selection", "Maximum selectable scrap spawn weight", (ConfigEntryBase)(object)scrapRarityMax), ("Gift Box - Scrap Selection", "Scrap spawn weight influence percentage (%)", (ConfigEntryBase)(object)scrapRarityInfluence), ("Gift Box - Scrap Item Value", "Chance for scrap item to inherit gift box value (%)", (ConfigEntryBase)(object)scrapValueIsGiftBoxChance), ("Gift Box - Scrap Item Value", "Chance for scrap item to receive scrap value addition (%)", (ConfigEntryBase)(object)scrapValueAdditionChance), ("Gift Box - Scrap Item Value", "Minimum scrap item value addition", (ConfigEntryBase)(object)scrapValueAdditionMin), ("Gift Box - Scrap Item Value", "Maximum scrap item value addition", (ConfigEntryBase)(object)scrapValueAdditionMax), ("Gift Box - Scrap Item Value", "Chance for scrap item to receive scrap value multiplier (%)", (ConfigEntryBase)(object)scrapValueMultiplierChance), ("Gift Box - Scrap Item Value", "Minimum scrap item value multiplier (%)", (ConfigEntryBase)(object)scrapValueMultiplierMin), ("Gift Box - Scrap Item Value", "Maximum scrap item value multiplier (%)", (ConfigEntryBase)(object)scrapValueMultiplierMax), ("Gift Box - Store Item Selection", "Minimum selectable store item price", (ConfigEntryBase)(object)storeItemPriceMin), ("Gift Box - Store Item Selection", "Maximum selectable store item price", (ConfigEntryBase)(object)storeItemPriceMax), ("Gift Box - Store Item Selection", "Store item price influence percentage (%)", (ConfigEntryBase)(object)storeItemPriceInfluence), ("Gift Box Behaviors", "Disable All Mod Mechanics", (ConfigEntryBase)(object)giftboxMechanicsDisabled), ("Gift Box Behaviors", "Disable Gift Box Duplicate Sounds Bugfix", (ConfigEntryBase)(object)giftboxDupeSoundsBugFixDisabled), ("Gift Box Behaviors", "Disable Gift Box Setting Tool Scrap Value Bugfix", (ConfigEntryBase)(object)giftboxToolScrapValueBugfixDisabled));
			ValidateConfigAndApplyPatches();
			Log("[v1.1.1] Finished loading!");
		}

		private void MigrateOldEntries(params (string oldSection, string oldKey, ConfigEntryBase newEntry)[] migrations)
		{
			Dictionary<ConfigDefinition, string> orphanedEntries = (Dictionary<ConfigDefinition, string>)(AccessTools.DeclaredPropertyGetter(typeof(ConfigFile), "OrphanedEntries")?.Invoke(((BaseUnityPlugin)this).Config, Array.Empty<object>()));
			if (orphanedEntries == null)
			{
				Log((LogLevel)4, "Unable to retrieve orphaned entries!");
				return;
			}
			int migrationsPerformed = 0;
			CollectionExtensions.Do<(string, string, ConfigEntryBase)>((IEnumerable<(string, string, ConfigEntryBase)>)migrations, (Action<(string, string, ConfigEntryBase)>)delegate((string oldSection, string oldKey, ConfigEntryBase newEntry) migration)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Expected O, but got Unknown
				ConfigDefinition val = new ConfigDefinition(migration.oldSection, migration.oldKey);
				if (orphanedEntries.TryGetValue(val, out string value))
				{
					migration.newEntry.SetSerializedValue(value);
					migrationsPerformed++;
					Log($"[{migrationsPerformed} Migrated [{val.Section}].[{val.Key}] to [{migration.newEntry.Definition.Section}].[{migration.newEntry.Definition.Key}]");
					orphanedEntries.Remove(val);
				}
			});
			if (migrationsPerformed != 0)
			{
				Log($"Successfully migrated {migrationsPerformed} orphan entries! Saving to file...");
				((BaseUnityPlugin)this).Config.Save();
				Log("Migrations saved to file!");
			}
		}
	}
}
namespace LC_GiftBox_Config.Patches.GiftBoxItemPatches
{
	[StaticNetcode]
	[HarmonyPatch(typeof(GiftBoxItem))]
	public static class GiftBoxItemPatch
	{
		public class GiftBoxModdedParams
		{
			[ES3Serializable]
			public bool CanEggsplode;

			[ES3Serializable]
			public bool ScrapHasGiftBoxValue;

			[ES3Serializable]
			public int ScrapValue;

			[ES3Serializable]
			public int NestedScrapId = -1;
		}

		public class GiftBoxModdedBehavior : MonoBehaviour
		{
			public GiftBoxModdedParams Params;

			public GiftBoxModdedBehavior()
			{
				Params = new GiftBoxModdedParams();
			}

			public GiftBoxModdedBehavior(GiftBoxModdedParams _Params)
			{
				Params = _Params;
			}

			public static implicit operator GiftBoxModdedParams?(GiftBoxModdedBehavior? component)
			{
				return component?.Params;
			}
		}

		public const int GIFTBOX_ITEM_ID = 152767;

		public static Item? _GIFTBOX_ITEM = null;

		public static GameObject? _EGGSPLOSION = null;

		public static AudioClip? _EGGPOP = null;

		public static List<int> giftboxBehaviors = new List<int>(5) { 0, 0, 0, 0, 0 };

		public const int DO_NOTHING = 0;

		public const int SPAWN_STORE_ITEM = 1;

		public const int SPAWN_SCRAP = 2;

		public const int SPAWN_GIFTBOX = 3;

		public const int SPAWN_NOTHING = 4;

		public static GiftBoxModdedParams? parentGiftboxParams = null;

		public static Terminal? _terminal = null;

		public static Item[] _terminalBuyableItemsList = Array.Empty<Item>();

		public static List<Item> _filteredStoreItems = new List<Item>();

		public static List<double> _filteredStoreItemWeights = new List<double>();

		public static List<SpawnableItemWithRarity> _currentLevelSpawnableScrap = new List<SpawnableItemWithRarity>();

		public static List<SpawnableItemWithRarity> _filteredScrapItems = new List<SpawnableItemWithRarity>();

		public static List<double> _filteredScrapItemWeights = new List<double>();

		public static Item GIFTBOX_ITEM => _GIFTBOX_ITEM ?? (_GIFTBOX_ITEM = StartOfRound.Instance.allItemsList.itemsList.ToList().First((Item item) => item.itemId == 152767));

		public static GameObject EGGSPLOSION => _EGGSPLOSION ?? (_EGGSPLOSION = Resources.FindObjectsOfTypeAll<GameObject>().First((GameObject obj) => ((Object)obj).name == "EasterEggExplosionParticle"));

		public static AudioClip? EGGPOP => _EGGPOP ?? (_EGGPOP = Resources.FindObjectsOfTypeAll<AudioClip>().First((AudioClip clip) => ((Object)clip).name == "EasterEggPop"));

		public static List<Item> filteredStoreItems
		{
			get
			{
				if ((Object)(object)_terminal == (Object)null || !((Behaviour)_terminal).isActiveAndEnabled)
				{
					_terminal = Object.FindAnyObjectByType<Terminal>();
					_terminalBuyableItemsList = Array.Empty<Item>();
				}
				if (_terminalBuyableItemsList != _terminal?.buyableItemsList)
				{
					_terminalBuyableItemsList = _terminal?.buyableItemsList ?? Array.Empty<Item>();
					_filteredStoreItems.Clear();
				}
				if (_filteredStoreItems.Count == 0)
				{
					_filteredStoreItems = _terminalBuyableItemsList.Where((Item item) => item.creditsWorth >= Plugin.storeItemPriceMin.Value && item.creditsWorth <= Plugin.storeItemPriceMax.Value).ToList();
				}
				return _filteredStoreItems;
			}
			set
			{
				if (value == null)
				{
					_filteredStoreItems.Clear();
				}
				else
				{
					_filteredStoreItems = value;
				}
			}
		}

		public static List<double> filteredStoreItemWeights
		{
			get
			{
				_ = filteredStoreItems;
				if (_filteredStoreItemWeights.Count == 0)
				{
					_filteredStoreItemWeights = _filteredStoreItems.Select((Item item) => Math.Pow(item.creditsWorth, (double)Plugin.scrapValueInfluence.Value / 100.0)).ToList();
				}
				return _filteredStoreItemWeights;
			}
			set
			{
				if (value == null)
				{
					_filteredStoreItemWeights.Clear();
				}
				else
				{
					_filteredStoreItemWeights = value;
				}
			}
		}

		public static List<SpawnableItemWithRarity> filteredScrapItems
		{
			get
			{
				if (_currentLevelSpawnableScrap != RoundManager.Instance.currentLevel.spawnableScrap)
				{
					_currentLevelSpawnableScrap = RoundManager.Instance.currentLevel.spawnableScrap;
					_filteredScrapItems.Clear();
					_filteredScrapItemWeights.Clear();
				}
				if (_filteredScrapItems.Count == 0)
				{
					_filteredScrapItems = _currentLevelSpawnableScrap.Where((SpawnableItemWithRarity item) => item.spawnableItem.itemId != 152767 && item.spawnableItem.minValue >= Plugin.scrapValueMin.Value && item.spawnableItem.maxValue <= Plugin.scrapValueMax.Value && item.rarity >= Plugin.scrapRarityMin.Value && item.rarity <= Plugin.scrapRarityMax.Value).ToList();
				}
				return _filteredScrapItems;
			}
			set
			{
				if (value == null)
				{
					_filteredScrapItems.Clear();
				}
				else
				{
					_filteredScrapItems = value;
				}
			}
		}

		public static List<double> filteredScrapItemWeights
		{
			get
			{
				_ = filteredScrapItems;
				if (_filteredScrapItemWeights.Count == 0)
				{
					_filteredScrapItemWeights = _filteredScrapItems.Select((SpawnableItemWithRarity item) => Math.Pow((double)(item.spawnableItem.minValue + item.spawnableItem.maxValue) / 2.0, (double)Plugin.scrapValueInfluence.Value / 100.0) + Math.Pow(item.rarity, (double)Plugin.scrapRarityInfluence.Value / 100.0)).ToList();
				}
				return _filteredScrapItemWeights;
			}
			set
			{
				if (value == null)
				{
					_filteredScrapItemWeights.Clear();
				}
				else
				{
					_filteredScrapItemWeights = value;
				}
			}
		}

		[HarmonyPatch("GetItemDataToSave")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> GetItemDataToSave(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIndex(iLStepper.Instructions.Count);
			iLStepper.GotoIL((CodeInstruction code) => CodeInstructionExtensions.LoadsConstant(code, 0L), null, 0, reverse: true);
			iLStepper.OverwriteIL(CodeInstructionPolyfills.LoadConstant(int.MaxValue));
			return iLStepper.Instructions;
		}

		public static bool OverrideLoadItemSaveData(GiftBoxItem giftbox, int saveData)
		{
			GiftBoxModdedParams giftBoxModdedParams = ((Component)giftbox).GetComponent<GiftBoxModdedBehavior>();
			if (giftBoxModdedParams == null)
			{
				return false;
			}
			giftbox.objectInPresentItem = ((saveData == int.MaxValue) ? null : StartOfRound.Instance.allItemsList.itemsList.ElementAtOrDefault(saveData));
			giftbox.objectInPresent = giftbox.objectInPresentItem?.spawnPrefab;
			giftbox.objectInPresentValue = giftBoxModdedParams.ScrapValue;
			giftbox.loadedItemFromSave = true;
			return true;
		}

		[HarmonyPatch("LoadItemSaveData")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> LoadItemSaveData(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GrabbableObject), "LoadItemSaveData"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.Start] Call GrabbableObject.LoadItemSaveData() not found!");
			iLStepper.GotoIndex(null, 1);
			Label label = iLStepper.DeclareLabel();
			iLStepper.InsertIL(new List<CodeInstruction>(4)
			{
				CodeInstructionPolyfills.LoadArgument(0),
				CodeInstructionPolyfills.LoadArgument(1),
				CodeInstructionPolyfills.Call(typeof(GiftBoxItemPatch), "OverrideLoadItemSaveData"),
				new CodeInstruction(OpCodes.Brtrue, (object)label)
			});
			iLStepper.GotoIL((CodeInstruction code) => code.StoresField(typeof(GiftBoxItem), "loadedItemFromSave"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.Start] Store field GrabbableObject.loadedItemFromSave not found!");
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label }));
			return iLStepper.Instructions;
		}

		public static bool InitGiftboxModdedBehavior(GiftBoxItem giftbox, Random giftboxBehaviorSeed, Random valueBehaviorSeed)
		{
			int randomWeightedIndex = Probability.GetRandomWeightedIndex(giftboxBehaviors, giftboxBehaviorSeed);
			if (randomWeightedIndex == 0)
			{
				return false;
			}
			GiftBoxModdedParams @params = ((Component)giftbox).gameObject.AddComponent<GiftBoxModdedBehavior>().Params;
			@params.CanEggsplode = giftboxBehaviorSeed.Next(0, 100) < Plugin.giftboxEggsplosionChance.Value;
			switch (randomWeightedIndex)
			{
			case 1:
			{
				int randomWeightedIndex3 = Probability.GetRandomWeightedIndex(filteredStoreItemWeights, giftboxBehaviorSeed);
				if (randomWeightedIndex3 != -1)
				{
					giftbox.objectInPresentItem = filteredStoreItems[randomWeightedIndex3];
					giftbox.objectInPresent = giftbox.objectInPresentItem.spawnPrefab;
				}
				break;
			}
			case 3:
				giftbox.objectInPresentItem = ((GrabbableObject)giftbox).itemProperties;
				giftbox.objectInPresent = giftbox.objectInPresentItem.spawnPrefab;
				if (parentGiftboxParams != null)
				{
					@params.NestedScrapId = parentGiftboxParams.NestedScrapId;
				}
				else
				{
					int randomWeightedIndex2 = Probability.GetRandomWeightedIndex(filteredScrapItemWeights, giftboxBehaviorSeed);
					Item nestedScrapItem = filteredScrapItems.ElementAtOrDefault(randomWeightedIndex2)?.spawnableItem;
					if (Object.op_Implicit((Object)(object)nestedScrapItem))
					{
						@params.NestedScrapId = StartOfRound.Instance.allItemsList.itemsList.FindIndex((Item item) => (Object)(object)item == (Object)(object)nestedScrapItem);
					}
				}
				goto case 2;
			case 2:
				if (randomWeightedIndex == 2)
				{
					int num = parentGiftboxParams?.NestedScrapId ?? Probability.GetRandomWeightedIndex(filteredScrapItemWeights, giftboxBehaviorSeed);
					if (num == -1)
					{
						break;
					}
					giftbox.objectInPresentItem = filteredScrapItems[num].spawnableItem;
					giftbox.objectInPresent = giftbox.objectInPresentItem.spawnPrefab;
				}
				giftbox.objectInPresentValue = valueBehaviorSeed.Next(giftbox.objectInPresentItem.minValue, giftbox.objectInPresentItem.maxValue);
				if (valueBehaviorSeed.Next(0, 100) < Plugin.scrapValueAdditionChance.Value)
				{
					giftbox.objectInPresentValue += valueBehaviorSeed.Next(Plugin.scrapValueAdditionMin.Value, Plugin.scrapValueAdditionMax.Value + 1);
				}
				if (valueBehaviorSeed.Next(0, 100) < Plugin.scrapValueMultiplierChance.Value)
				{
					giftbox.objectInPresentValue = (int)((double)giftbox.objectInPresentValue * ((double)Plugin.scrapValueMultiplierMin.Value + (double)(Plugin.scrapValueMultiplierMax.Value - Plugin.scrapValueMultiplierMin.Value) * valueBehaviorSeed.NextDouble()) / 100.0);
				}
				if (valueBehaviorSeed.Next(0, 100) < Plugin.scrapValueIsGiftBoxChance.Value)
				{
					@params.ScrapHasGiftBoxValue = true;
				}
				break;
			default:
				throw new Exception("[Patches.GiftBoxItemPatches.GiftBoxItemPatch.InitGiftboxModdedBehavior] Giftbox Behavior selection failed! This should never happen!");
			case 4:
				break;
			}
			@params.ScrapValue = giftbox.objectInPresentValue;
			return true;
		}

		[HarmonyPatch("Start")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Start(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			filteredStoreItems = null;
			filteredScrapItems = null;
			giftboxBehaviors[0] = Plugin.doNothingChance.Value;
			giftboxBehaviors[1] = Plugin.spawnStoreItemChance.Value;
			giftboxBehaviors[2] = Plugin.spawnScrapChance.Value;
			giftboxBehaviors[3] = Plugin.spawnGiftBoxChance.Value;
			giftboxBehaviors[4] = Plugin.spawnNothingChance.Value;
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.LoadsProperty(typeof(NetworkBehaviour), "IsServer"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.Start] Property NetworkBehaviour.IsServer not found!");
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(new List<CodeInstruction>(6)
			{
				CodeInstructionPolyfills.LoadArgument(0),
				CodeInstructionPolyfills.LoadLocal(0),
				CodeInstructionPolyfills.LoadLocal(1),
				CodeInstructionPolyfills.Call(typeof(GiftBoxItemPatch), "InitGiftboxModdedBehavior"),
				new CodeInstruction(OpCodes.Not, (object)null),
				new CodeInstruction(OpCodes.And, (object)null)
			});
			return iLStepper.Instructions;
		}

		public static void NestedGiftboxFun(GiftBoxItem giftbox, GrabbableObject? spawnedObj)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)spawnedObj == (Object)null) && spawnedObj.itemProperties.itemId == 152767)
			{
				((Component)spawnedObj).transform.localScale = ((Component)giftbox).transform.localScale * 0.925f;
				((Object)spawnedObj).name = "Nested " + ((Object)giftbox).name;
				ScanNodeProperties componentInChildren = ((Component)giftbox).GetComponentInChildren<ScanNodeProperties>();
				ScanNodeProperties componentInChildren2 = ((Component)spawnedObj).GetComponentInChildren<ScanNodeProperties>();
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.headerText = "Nested " + componentInChildren.headerText;
				}
				else
				{
					Plugin.Log((LogLevel)4, "Failed to prepare nested giftbox scan node :(");
				}
				GiftBoxModdedParams giftBoxModdedParams = ((Component)spawnedObj).GetComponent<GiftBoxModdedBehavior>();
			}
		}

		public static bool OverrideOpenGiftBox(GiftBoxItem giftbox)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			GiftBoxModdedParams giftBoxModdedParams = ((Component)giftbox).GetComponent<GiftBoxModdedBehavior>();
			if (giftBoxModdedParams == null)
			{
				return false;
			}
			if (giftBoxModdedParams.ScrapHasGiftBoxValue)
			{
				giftbox.objectInPresentValue = ((GrabbableObject)giftbox).scrapValue;
			}
			parentGiftboxParams = giftBoxModdedParams;
			GrabbableObject val = SpawnGiftItem(giftbox);
			parentGiftboxParams = null;
			NestedGiftboxFun(giftbox, val);
			if ((Object)(object)val == (Object)null && giftBoxModdedParams.CanEggsplode)
			{
				EggsplosionClientRpc(NetworkObjectReference.op_Implicit(((Component)giftbox).gameObject));
			}
			return true;
		}

		[HarmonyPatch("OpenGiftBoxServerRpc")]
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		public static GrabbableObject? SpawnGiftItem(GiftBoxItem giftbox)
		{
			Transpiler(null, null, null);
			return null;
			static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
			{
				//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f2: Expected O, but got Unknown
				//IL_0202: Unknown result type (might be due to invalid IL or missing references)
				//IL_021a: Expected O, but got Unknown
				//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ae: Expected O, but got Unknown
				ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
				iLStepper.GotoIL((CodeInstruction code) => code.StoresLocal(0), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] Store Local 0 (gameObject) not found");
				iLStepper.GotoIL(ILPatterns.NextEmptyStack(), null, 1, reverse: true, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] OpCodes.Ldnull not found");
				iLStepper.RemoveIL(0, iLStepper.CurrentIndex, shiftCurrentIndex: true, pinLabels: false, pinBlocks: false);
				Func<CodeInstruction, bool> searchCondition = (CodeInstruction code) => code.LoadsString("Error: There is no object in gift box!");
				int? num = null;
				iLStepper.GotoIL(searchCondition, num, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] \"no object\" error message not found");
				num = 1 + iLStepper.FindIL(ILPatterns.NextEmptyStack(), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] Call Debug.LogError(object) not found");
				iLStepper.RemoveIL(null, num);
				iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GrabbableObject), "SetScrapValue", new Type[1] { typeof(int) }), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] Call GrabbableObject.SetScrapValue(int) not found");
				num = null;
				iLStepper.GotoIndex(num, 1);
				num = iLStepper.FindIL(ILPatterns.NextEmptyStack(), null, 0, reverse: true, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.SpawnGiftItem] 1st Load Local 4 (component) not found");
				List<CodeInstruction> collection = iLStepper.RemoveIL(null, num, shiftCurrentIndex: true, pinLabels: false, pinBlocks: false);
				Label label = iLStepper.DeclareLabel();
				List<CodeInstruction> list = new List<CodeInstruction>();
				list.Add(CodeInstructionPolyfills.LoadLocal(4));
				list.Add(CodeInstructionPolyfills.LoadField(typeof(GrabbableObject), "itemProperties"));
				list.Add(CodeInstructionPolyfills.LoadField(typeof(Item), "isScrap"));
				list.Add(new CodeInstruction(OpCodes.Brfalse, (object)label));
				list.AddRange(collection);
				list.Add(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label }));
				List<CodeInstruction> list2 = iLStepper.InsertIL(list);
				iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GiftBoxItem), "OpenGiftBoxClientRpc"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc_DuplicateSoundsBugfix] Call GiftBoxItem.OpenGiftBoxClientRpc not found!");
				iLStepper.GotoIndex(null, 1);
				iLStepper.InsertIL(new List<CodeInstruction>(2)
				{
					CodeInstructionPolyfills.LoadLocal(4),
					new CodeInstruction(OpCodes.Ret, (object)null)
				}, null, shiftCurrentIndex: true, pinLabels: false, pinBlocks: false);
				iLStepper.GotoIndex(iLStepper.Instructions.Count);
				iLStepper.GotoIL((CodeInstruction code) => code.opcode == OpCodes.Ret, null, 0, reverse: true, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc_DuplicateSoundsBugfix] Final return not found!");
				iLStepper.InsertIL(CodeInstructionPolyfills.LoadNull());
				return iLStepper.Instructions;
			}
		}

		[HarmonyPatch("OpenGiftBoxServerRpc")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> OpenGiftBoxServerRpc(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.StoresLocal(0), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc] Store Local 0 (gameObject) not found");
			iLStepper.GotoIL(ILPatterns.NextEmptyStack(), null, 1, reverse: true, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc] Beginning of Store Local 0 (gameObject) not found");
			Label label = iLStepper.DeclareLabel();
			iLStepper.InsertIL(new List<CodeInstruction>(3)
			{
				CodeInstructionPolyfills.LoadArgument(0),
				CodeInstructionPolyfills.Call(typeof(GiftBoxItemPatch), "OverrideOpenGiftBox"),
				new CodeInstruction(OpCodes.Brtrue, (object)label)
			});
			iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GiftBoxItem), "OpenGiftBoxNoPresentClientRpc"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc] Call GiftBoxItem.OpenGiftBoxNoPresentClientRpc not found!");
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label }));
			return iLStepper.Instructions;
		}

		[ClientRpc]
		public static void EggsplosionClientRpc(NetworkObjectReference giftboxNGO)
		{
			//IL_0000: 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_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)
			GameObject obj = NetworkObjectReference.op_Implicit(giftboxNGO);
			GiftBoxItem val = ((obj != null) ? obj.GetComponent<GiftBoxItem>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				if ((Object)(object)EGGSPLOSION != (Object)null)
				{
					Transform val2 = (((GrabbableObject)val).isInElevator ? StartOfRound.Instance.elevatorTransform : RoundManager.Instance.mapPropsContainer.transform);
					Object.Instantiate<GameObject>(EGGSPLOSION, ((Component)val).transform.position, Quaternion.identity, val2);
				}
				else
				{
					Plugin.Log((LogLevel)4, "EGGSPLOSION VFX not found!");
				}
				if ((Object)(object)EGGPOP != (Object)null)
				{
					val.presentAudio.PlayOneShot(EGGPOP, 0.67f);
					WalkieTalkie.TransmitOneShotAudio(val.presentAudio, EGGPOP, 0.67f);
					RoundManager.Instance.PlayAudibleNoise(((Component)val.presentAudio).transform.position, 15f, 0.67f, 1, ((GrabbableObject)val).isInShipRoom && StartOfRound.Instance.hangarDoorsClosed, 0);
				}
				else
				{
					Plugin.Log((LogLevel)4, "EGGSPLOSION SFX not found!");
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> waitForGiftPresentToSpawnOnClient(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.StoresField(typeof(GrabbableObject), "reachedFloorTarget"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.waitForGiftPresentToSpawnOnClient] Store Field GrabbableObject.reachedFloorTarget not found");
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(new List<CodeInstruction>(3)
			{
				CodeInstructionPolyfills.LoadLocal(1),
				CodeInstructionPolyfills.LoadLocal(2),
				CodeInstructionPolyfills.Call(typeof(GiftBoxItemPatch), "NestedGiftboxFun")
			});
			return iLStepper.Instructions;
		}

		[HarmonyPatch("OpenGiftBoxServerRpc")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> OpenGiftBoxServerRpc_DuplicateSoundsBugfix(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			if (Plugin.giftboxDupeSoundsBugFixDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GiftBoxItem), "OpenGiftBoxClientRpc"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc_DuplicateSoundsBugfix] Call GiftBoxItem.OpenGiftBoxClientRpc not found!");
			iLStepper.GotoIndex(null, 1);
			Label label = iLStepper.DeclareLabel();
			iLStepper.InsertIL(new CodeInstruction(OpCodes.Br, (object)label), null, shiftCurrentIndex: true, pinLabels: false, pinBlocks: false);
			iLStepper.GotoIL((CodeInstruction code) => code.Calls(typeof(GiftBoxItem), "OpenGiftBoxNoPresentClientRpc"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.OpenGiftBoxServerRpc_DuplicateSoundsBugfix] Call GiftBoxItem.OpenGiftBoxNoPresentClientRpc not found!");
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label }));
			return iLStepper.Instructions;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> waitForGiftPresentToSpawnOnClient_ToolBugfix(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			if (Plugin.giftboxToolScrapValueBugfixDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.StoresField(typeof(RoundManager), "totalScrapValueInLevel"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.waitForGiftPresentToSpawnOnClient_ToolBugfix] Store Field RoundManager.totalScrapValueInLevel not found");
			int? num = null;
			iLStepper.GotoIndex(num, 1);
			Label label = iLStepper.DeclareLabel();
			List<CodeInstruction> list = new List<CodeInstruction>
			{
				CodeInstructionPolyfills.LoadLocal(2),
				CodeInstructionPolyfills.LoadField(typeof(GrabbableObject), "itemProperties"),
				CodeInstructionPolyfills.LoadField(typeof(Item), "isScrap"),
				new CodeInstruction(OpCodes.Brfalse, (object)label)
			};
			num = 1 + iLStepper.FindIL((CodeInstruction code) => code.Calls(typeof(GrabbableObject), "SetScrapValue"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.GiftBoxItemPatch.waitForGiftPresentToSpawnOnClient_ToolBugfix] Call GrabbableObject.SetScrapValue not found");
			list.AddRange(iLStepper.RemoveIL(null, num, shiftCurrentIndex: true, pinLabels: false, pinBlocks: false));
			list.Add(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Nop, (object)null), new Label[1] { label }));
			iLStepper.InsertIL(list);
			return iLStepper.Instructions;
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal static class RoundManagerPatch
	{
		internal static void AnomalouslySpawnGiftBoxes(RoundManager roundmanager, List<Item> ScrapToSpawn, int spawnOneItemIndex, List<SpawnableItemWithRarity> spawnableScrap)
		{
			if (spawnOneItemIndex == -1 || spawnableScrap[spawnOneItemIndex].spawnableItem.itemId == 152767)
			{
				Random anomalyRandom = roundmanager.AnomalyRandom;
				if (anomalyRandom.Next(0, 100) < Plugin.giftboxSpawnChance.Value)
				{
					int count = anomalyRandom.Next(Plugin.giftboxSpawnMin.Value, Plugin.giftboxSpawnMax.Value + 1);
					ScrapToSpawn.AddRange(Enumerable.Repeat<Item>(GiftBoxItemPatch.GIFTBOX_ITEM, count).ToList());
				}
			}
		}

		internal static void AdjustGiftBoxSpawnWeight(RoundManager roundmanager, int[] weights, List<SpawnableItemWithRarity> spawnableScrap)
		{
			Random anomalyRandom = roundmanager.AnomalyRandom;
			if (weights.Length != spawnableScrap.Count)
			{
				Plugin.Log((LogLevel)2, "[LC_GiftBox_Config.Patches.RoundManagerPatch.AdjustGiftBoxSpawnWeight] weights length does not match spawnableScrap length! Wonkiness may occur!");
			}
			for (int i = 0; i < Math.Min(spawnableScrap.Count, weights.Length); i++)
			{
				if (spawnableScrap[i].spawnableItem.itemId == 152767)
				{
					if (anomalyRandom.Next(0, 100) < Plugin.giftboxRarityAdditionChance.Value)
					{
						weights[i] += anomalyRandom.Next(Plugin.giftboxRarityAdditionMin.Value, Plugin.giftboxRarityAdditionMax.Value + 1);
					}
					if (anomalyRandom.Next(0, 100) < Plugin.giftboxRarityMultiplierChance.Value)
					{
						weights[i] = (int)((double)weights[i] * ((double)Plugin.giftboxRarityMultiplierMin.Value + (double)(Plugin.giftboxRarityMultiplierMax.Value - Plugin.giftboxRarityMultiplierMin.Value) * anomalyRandom.NextDouble()) / 100.0);
					}
				}
			}
		}

		internal static void AdjustGiftBoxValue(RoundManager roundmanager, GrabbableObject component, List<int> scrapValues)
		{
			if (component.itemProperties.itemId == 152767)
			{
				Random anomalyRandom = roundmanager.AnomalyRandom;
				if (anomalyRandom.Next(0, 100) < Plugin.giftboxValueAdditionChance.Value)
				{
					scrapValues[scrapValues.Count - 1] += anomalyRandom.Next(Plugin.giftboxValueAdditionMin.Value, Plugin.giftboxValueAdditionMax.Value + 1);
				}
				if (anomalyRandom.Next(0, 100) < Plugin.giftboxValueMultiplierChance.Value)
				{
					scrapValues[scrapValues.Count - 1] = (int)((double)scrapValues[scrapValues.Count - 1] * ((double)Plugin.giftboxValueMultiplierMin.Value + (double)(Plugin.giftboxValueMultiplierMax.Value - Plugin.giftboxValueMultiplierMin.Value) * anomalyRandom.NextDouble()) / 100.0);
				}
			}
		}

		[HarmonyPatch("SpawnScrapInLevel")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> SpawnScrapInLevel(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper stepper = new ILStepper(methodIL, methodGenerator, methodBase);
			stepper.GotoIL((CodeInstruction code, int index) => code.StoresLocal(15) && index > 0 && CodeInstructionExtensions.LoadsConstant(stepper.Instructions[index - 1], 0L), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] For loop initialization (int j = 0;) not found");
			stepper.GotoIL((CodeInstruction code) => code.opcode.FlowControl == FlowControl.Branch, null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] For loop branch to control statement (j < this.currentLevel.spawnableScrap.Count;) not found");
			stepper.GotoIL((CodeInstruction code) => code.labels.Contains((Label)stepper.CurrentOperand), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] For loop control statement (j < this.currentLevel.spawnableScrap.Count;) not found");
			stepper.GotoIL((CodeInstruction code) => code.LoadsProperty(typeof(List<SpawnableItemWithRarity>), "Count"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Load Property List.Count (this.currentLevel.spawnableScrap.Count) not found");
			List<CodeInstruction> list = (from code in stepper.GetIL(stepper.FindIL(ILPatterns.NextEmptyStack(-1), null, 0, reverse: true, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Spawnable Scrap List (this.currentLevel.spawnableScrap) not found)"))
				select code.Clone()).ToList();
			stepper.GotoIndex(0);
			stepper.GotoIL((CodeInstruction code) => code.StoresField(stepper.GetLocal(0).LocalType, "ScrapToSpawn"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Store Field compilerClosureObj.ScrapToSpawn not found");
			stepper.GotoIndex(null, 1);
			ILStepper iLStepper = stepper;
			List<CodeInstruction> list2 = new List<CodeInstruction>();
			list2.Add(CodeInstructionPolyfills.LoadArgument(0));
			list2.Add(CodeInstructionPolyfills.LoadLocal(0));
			list2.Add(CodeInstructionPolyfills.LoadField(stepper.GetLocal(0).LocalType, "ScrapToSpawn"));
			list2.Add(CodeInstructionPolyfills.LoadLocal(2));
			list2.AddRange(list);
			list2.Add(CodeInstructionPolyfills.Call(typeof(RoundManagerPatch), "AnomalouslySpawnGiftBoxes"));
			iLStepper.InsertIL(list2);
			stepper.GotoIL((CodeInstruction code) => code.StoresLocal(6), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Store Local 6 (weights) not found");
			stepper.GotoIndex(null, 1);
			ILStepper iLStepper2 = stepper;
			CodeInstruction item = CodeInstructionPolyfills.LoadArgument(0);
			CodeInstruction item2 = CodeInstructionPolyfills.LoadLocal(6);
			list2 = list;
			List<CodeInstruction> list3 = new List<CodeInstruction>(3 + list2.Count);
			list3.Add(item);
			list3.Add(item2);
			list3.AddRange(list2);
			list3.Add(CodeInstructionPolyfills.Call(typeof(RoundManagerPatch), "AdjustGiftBoxSpawnWeight"));
			iLStepper2.InsertIL(list3);
			stepper.GotoIL((CodeInstruction code) => code.StoresField(typeof(GrabbableObject), "scrapValue"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Store field GrabbableObject.scrapValue not found");
			stepper.GotoIL((CodeInstruction code) => code.StoresLocal(4), null, 0, reverse: true, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Store Local 4 (num4) not found");
			stepper.GotoIL(ILPatterns.NextEmptyStack(), null, 1, reverse: true, "[Patches.GiftBoxItemPatches.RoundManagerPatch.SpawnScrapInLevel] Load Local 4 (num4) not found");
			stepper.InsertIL(new List<CodeInstruction>(4)
			{
				CodeInstructionPolyfills.LoadArgument(0),
				CodeInstructionPolyfills.LoadLocal(18),
				CodeInstructionPolyfills.LoadLocal(3),
				CodeInstructionPolyfills.Call(typeof(RoundManagerPatch), "AdjustGiftBoxValue")
			});
			return stepper.Instructions;
		}
	}
	[HarmonyPatch]
	internal static class SaveFilePatch
	{
		internal static readonly string GiftBoxModdedParamsSaveKey = Plugin.harmony.Id + ".giftboxModdedParamsDict";

		internal static Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams> GetGiftBoxModdedParamsDict()
		{
			Plugin.Log($"ES3 Key exists: {ES3.KeyExists(GiftBoxModdedParamsSaveKey, GameNetworkManager.Instance.currentSaveFileName)}");
			if (!ES3.KeyExists(GiftBoxModdedParamsSaveKey, GameNetworkManager.Instance.currentSaveFileName))
			{
				return new Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>();
			}
			CollectionExtensions.Do<KeyValuePair<int, GiftBoxItemPatch.GiftBoxModdedParams>>((IEnumerable<KeyValuePair<int, GiftBoxItemPatch.GiftBoxModdedParams>>)ES3.Load<Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>>(GiftBoxModdedParamsSaveKey, GameNetworkManager.Instance.currentSaveFileName), (Action<KeyValuePair<int, GiftBoxItemPatch.GiftBoxModdedParams>>)delegate(KeyValuePair<int, GiftBoxItemPatch.GiftBoxModdedParams> keypair)
			{
				Plugin.Log($"\t{keypair.Key} {keypair.Value}");
			});
			return ES3.Load<Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>>(GiftBoxModdedParamsSaveKey, GameNetworkManager.Instance.currentSaveFileName);
		}

		internal static void LoadGiftBoxModdedParams(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams> dict, int index, GrabbableObject grabbable)
		{
			Plugin.Log($"Dict Key [{index}] exists: {dict.ContainsKey(index)}");
			if (dict.ContainsKey(index))
			{
				Plugin.Log($"\t[{index}] {dict[index]}");
				((Component)grabbable).gameObject.AddComponent<GiftBoxItemPatch.GiftBoxModdedBehavior>().Params = dict[index];
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "LoadShipGrabbableItems")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> LoadShipGrabbableItems(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.LoadsString("Ship grabbable items list loaded. Count: {0}"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.SaveFilePatch.LoadShipGrabbableItems] String \"Ship grabbable items list loaded. Count: {0}\" not found");
			iLStepper.GotoIL(ILPatterns.NextEmptyStack(), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.SaveFilePatch.LoadShipGrabbableItems] Call Debug.Log not found");
			iLStepper.GotoIndex(null, 1);
			LocalVariableInfo local = iLStepper.DeclareLocal(typeof(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>));
			iLStepper.InsertIL(new List<CodeInstruction>(2)
			{
				CodeInstructionPolyfills.Call(typeof(SaveFilePatch), "GetGiftBoxModdedParamsDict"),
				CodeInstructionPolyfills.StoreLocal(local)
			});
			iLStepper.GotoIL((CodeInstruction code) => code.StoresLocal(0));
			iLStepper.GotoIndex(null, 1);
			iLStepper.InsertIL(new List<CodeInstruction>(4)
			{
				CodeInstructionPolyfills.LoadLocal(local),
				CodeInstructionPolyfills.LoadLocal(9),
				CodeInstructionPolyfills.LoadLocal(0),
				CodeInstructionPolyfills.Call(typeof(SaveFilePatch), "LoadGiftBoxModdedParams")
			});
			return iLStepper.Instructions;
		}

		internal static void SetGiftBoxModdedParamsInDict(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams> dict, int index, GrabbableObject grabbable)
		{
			GiftBoxItemPatch.GiftBoxModdedParams giftBoxModdedParams = ((Component)grabbable).GetComponent<GiftBoxItemPatch.GiftBoxModdedBehavior>();
			if (giftBoxModdedParams != null)
			{
				dict.Add(index, giftBoxModdedParams);
			}
		}

		internal static void SaveGiftBoxModdedParamsDict(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams> dict)
		{
			ES3.Save<Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>>(GiftBoxModdedParamsSaveKey, dict, GameNetworkManager.Instance.currentSaveFileName);
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SaveItemsInShip")]
		[HarmonyPriority(int.MinValue)]
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> SaveItemsInShip(IEnumerable<CodeInstruction> methodIL, ILGenerator methodGenerator, MethodBase methodBase)
		{
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			if (Plugin.giftboxMechanicsDisabled.Value)
			{
				return methodIL;
			}
			ILStepper iLStepper = new ILStepper(methodIL, methodGenerator, methodBase);
			iLStepper.GotoIL((CodeInstruction code) => code.LoadsString("shipGrabbableItemIDs"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.SaveFilePatch.SaveItemsInShip] String \"shipGrabbableItemIDs\" not found");
			iLStepper.InsertIL(new List<CodeInstruction>(4)
			{
				CodeInstructionPolyfills.LoadString(GiftBoxModdedParamsSaveKey),
				CodeInstructionPolyfills.LoadArgument(0),
				CodeInstructionPolyfills.LoadField(typeof(GameNetworkManager), "currentSaveFileName"),
				CodeInstructionPolyfills.Call(typeof(ES3), "DeleteKey", new Type[2]
				{
					typeof(string),
					typeof(string)
				})
			});
			iLStepper.GotoIL((CodeInstruction code) => code.StoresLocal(4));
			iLStepper.GotoIndex(null, 1);
			LocalVariableInfo local = iLStepper.DeclareLocal(typeof(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>));
			iLStepper.InsertIL(new List<CodeInstruction>(2)
			{
				CodeInstructionPolyfills.CallConstructor(typeof(Dictionary<int, GiftBoxItemPatch.GiftBoxModdedParams>)),
				CodeInstructionPolyfills.StoreLocal(local)
			});
			iLStepper.GotoIL((CodeInstruction code) => code.LoadsString("Saved data for item type: {0} - {1}"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.SaveFilePatch.SaveItemsInShip] String \"Saved data for item type: {0} - {1}\" not found");
			iLStepper.InsertIL(new List<CodeInstruction>(9)
			{
				CodeInstructionPolyfills.LoadLocal(local),
				CodeInstructionPolyfills.LoadLocal(1),
				CodeInstructionPolyfills.LoadProperty(typeof(List<int>), "Count"),
				CodeInstructionPolyfills.LoadConstant(1),
				new CodeInstruction(OpCodes.Sub, (object)null),
				CodeInstructionPolyfills.LoadLocal(0),
				CodeInstructionPolyfills.LoadLocal(6),
				new CodeInstruction(OpCodes.Ldelem_Ref, (object)null),
				CodeInstructionPolyfills.Call(typeof(SaveFilePatch), "SetGiftBoxModdedParamsInDict")
			});
			iLStepper.GotoIL((CodeInstruction code) => code.LoadsString("shipGrabbableItemPos"), null, 0, reverse: false, "[Patches.GiftBoxItemPatches.SaveFilePatch.SaveItemsInShip] String \"shipGrabbableItemPos\" not found");
			iLStepper.InsertIL(new List<CodeInstruction>(2)
			{
				CodeInstructionPolyfills.LoadLocal(local),
				CodeInstructionPolyfills.Call(typeof(SaveFilePatch), "SaveGiftBoxModdedParamsDict")
			});
			return iLStepper.Instructions;
		}
	}
}
namespace LC_GiftBox_Config.libs.Probability
{
	public static class Probability
	{
		public static int GetRandomWeightedIndex(List<double> weights, Random? randomSeed = null)
		{
			if (weights == null || weights.Count == 0)
			{
				Plugin.Log((LogLevel)4, "[libs.Probability.GetRandomWeightedIndex] Could not get random weighted index; list is empty or null.");
				return -1;
			}
			if (weights.Any((double weight) => weight < 0.0))
			{
				Plugin.Log((LogLevel)4, "[libs.Probability.GetRandomWeightedIndex] Could not get random weighted index; list contains negative weights.");
				return -1;
			}
			if (randomSeed == null)
			{
				randomSeed = new Random();
			}
			double num = weights.Sum();
			if (num <= 0.0)
			{
				return randomSeed.Next(0, weights.Count);
			}
			double randomValue = randomSeed.NextDouble() * weights.Sum();
			double accumulatedValue = 0.0;
			return weights.FindIndex((double weight) => (accumulatedValue += weight) > randomValue);
		}

		public static int GetRandomWeightedIndex(List<int> weights, Random? randomSeed = null)
		{
			if (weights == null || weights.Count == 0)
			{
				Plugin.Log((LogLevel)4, "[libs.Probability.GetRandomWeightedIndex] Could not get random weighted index; list is empty or null.");
				return -1;
			}
			if (weights.Any((int weight) => weight < 0))
			{
				Plugin.Log((LogLevel)4, "[libs.Probability.GetRandomWeightedIndex] Could not get random weighted index; list contains negative weights.");
				return -1;
			}
			if (randomSeed == null)
			{
				randomSeed = new Random();
			}
			int num = weights.Sum();
			if (num <= 0)
			{
				return randomSeed.Next(0, weights.Count);
			}
			int randomValue = randomSeed.Next(0, num);
			int accumulatedValue = 0;
			return weights.FindIndex((int weight) => (accumulatedValue += weight) > randomValue);
		}
	}
}
namespace LC_GiftBox_Config.libs.LethalConfigNicerizer
{
	internal static class LethalConfigNicerizer
	{
		internal const string LethalConfig_GUID = "ainavt.lc.lethalconfig";

		internal static bool CanHasNicerizationPlease => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static ConfigEntry<T> Nicerize<T>(ConfigEntry<T> entry, bool restartRequired = false)
		{
			if (entry is ConfigEntry<int>)
			{
				if (CanHasNicerizationPlease)
				{
					AddConfigItem(entry as ConfigEntry<int>, restartRequired);
				}
			}
			else if (entry is ConfigEntry<float>)
			{
				if (CanHasNicerizationPlease)
				{
					AddConfigItem(entry as ConfigEntry<float>, restartRequired);
				}
			}
			else if (entry is ConfigEntry<bool>)
			{
				if (CanHasNicerizationPlease)
				{
					AddConfigItem(entry as ConfigEntry<bool>, restartRequired);
				}
			}
			else if (entry is ConfigEntry<string>)
			{
				if (CanHasNicerizationPlease)
				{
					AddConfigItem(entry as ConfigEntry<string>, restartRequired);
				}
			}
			else
			{
				if (!(entry is ConfigEntry<Enum>))
				{
					throw new ArgumentException($"[libs.LethalConfigNicerizer.Nicerize] Cannot Nicerize ConfigEntry<{typeof(T)}>!");
				}
				if (CanHasNicerizationPlease)
				{
					AddConfigItem(entry as ConfigEntry<Enum>, restartRequired);
				}
			}
			return entry;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void AddConfigItem(ConfigEntry<int> entry, bool restartRequired = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (((ConfigEntryBase)entry).Description.AcceptableValues != null)
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(entry, restartRequired));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(entry, restartRequired));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void AddConfigItem(ConfigEntry<float> entry, bool restartRequired = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (((ConfigEntryBase)entry).Description.AcceptableValues != null)
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(entry, restartRequired));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(entry, restartRequired));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void AddConfigItem(ConfigEntry<bool> entry, bool restartRequired = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(entry, restartRequired));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void AddConfigItem(ConfigEntry<string> entry, bool restartRequired = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (((ConfigEntryBase)entry).Description.AcceptableValues != null)
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextDropDownConfigItem(entry, restartRequired));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(entry, restartRequired));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void AddConfigItem(ConfigEntry<Enum> entry, bool restartRequired = false)
		{
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem<Enum>(entry, restartRequired));
		}
	}
}
namespace LC_GiftBox_Config.libs.ILStepper
{
	public static class ILPatterns
	{
		public static int? StackSizeDelta(StackBehaviour stackBehaviour)
		{
			switch (stackBehaviour)
			{
			case StackBehaviour.Pop0:
				return 0;
			case StackBehaviour.Pop1:
				return -1;
			case StackBehaviour.Pop1_pop1:
				return -2;
			case StackBehaviour.Popi:
				return -1;
			case StackBehaviour.Popi_pop1:
				return -2;
			case StackBehaviour.Popi_popi:
				return -2;
			case StackBehaviour.Popi_popi8:
				return -2;
			case StackBehaviour.Popi_popi_popi:
				return -3;
			case StackBehaviour.Popi_popr4:
				return -2;
			case StackBehaviour.Popi_popr8:
				return -2;
			case StackBehaviour.Popref:
				return -1;
			case StackBehaviour.Popref_pop1:
				return -2;
			case StackBehaviour.Popref_popi:
				return -2;
			case StackBehaviour.Popref_popi_popi:
				return -3;
			case StackBehaviour.Popref_popi_popi8:
				return -3;
			case StackBehaviour.Popref_popi_popr4:
				return -3;
			case StackBehaviour.Popref_popi_popr8:
				return -3;
			case StackBehaviour.Popref_popi_popref:
				return -3;
			case StackBehaviour.Push0:
				return 0;
			case StackBehaviour.Push1:
				return 1;
			case StackBehaviour.Push1_push1:
				return 2;
			case StackBehaviour.Pushi:
				return 1;
			case StackBehaviour.Pushi8:
				return 1;
			case StackBehaviour.Pushr4:
				return 1;
			case StackBehaviour.Pushr8:
				return 1;
			case StackBehaviour.Pushref:
				return 1;
			case StackBehaviour.Popref_popi_pop1:
				return -3;
			case StackBehaviour.Varpop:
			case StackBehaviour.Varpush:
				return null;
			default:
				throw new ArgumentOutOfRangeException($"stackBehaviour {stackBehaviour} is an invalid value");
			}
		}

		public static int? StackSizeDelta(OpCode opCode, object operand)
		{
			if (opCode == OpCodes.Calli)
			{
				return null;
			}
			if (opCode.FlowControl == FlowControl.Call)
			{
				MethodInfo methodInfo = operand as MethodInfo;
				if (methodInfo == null)
				{
					return null;
				}
				int num = -methodInfo.GetParameters().Count();
				if (opCode != OpCodes.Newobj && methodInfo.CallingConvention.HasFlag(CallingConventions.HasThis) && !methodInfo.CallingConvention.HasFlag(CallingConventions.ExplicitThis))
				{
					num--;
				}
				if (opCode == OpCodes.Newobj || methodInfo.ReturnType != typeof(void))
				{
					num++;
				}
				return num;
			}
			int? num2 = StackSizeDelta(opCode.StackBehaviourPush);
			int? num3 = StackSizeDelta(opCode.StackBehaviourPop);
			if (!num2.HasValue || !num3.HasValue)
			{
				return null;
			}
			return num2 + num3;
		}

		public static int? StackSizeDelta(CodeInstruction code)
		{
			return StackSizeDelta(code.opcode, code.operand);
		}

		public static bool EmptiesStack(OpCode opcode)
		{
			FlowControl flowControl = opcode.FlowControl;
			if (flowControl == FlowControl.Branch || (uint)(flowControl - 7) <= 1u)
			{
				return true;
			}
			return false;
		}

		public static bool EmptiesStack(CodeInstruction code)
		{
			return EmptiesStack(code.opcode);
		}

		public static Func<CodeInstruction, int, bool> NextEmptyStack(int startSize = 0)
		{
			return delegate(CodeInstruction code, int index)
			{
				if (EmptiesStack(code))
				{
					return true;
				}
				int num = StackSizeDelta(code) ?? throw new ArgumentException($"[libs.ILPatterns.NextEmptyStack] Encountered uncountable instruction [{index}] {code}");
				return (startSize += num) == 0;
			};
		}
	}
	public class ILStepper
	{
		public readonly List<CodeInstruction> Instructions;

		public int CurrentIndex;

		public readonly ILGenerator Generator;

		public readonly Dictionary<int, LocalVariableInfo> Locals;

		public readonly Dictionary<int, Label> Labels;

		public CodeInstruction CurrentInstruction => Instructions[CurrentIndex];

		public OpCode CurrentOpCode => CurrentInstruction.opcode;

		public object? CurrentOperand => CurrentInstruction.operand;

		public ILStepper(IEnumerable<CodeInstruction> codes, ILGenerator generator, MethodBase original, int index = 0)
		{
			Instructions = codes.ToList();
			CurrentIndex = index;
			Generator = generator;
			Locals = (from code in Instructions
				select code.operand as LocalVariableInfo into local
				where local != null
				select local).Distinct().ToDictionary((LocalVariableInfo local) => local.LocalIndex, (LocalVariableInfo local) => local);
			Labels = Instructions.SelectMany((CodeInstruction code) => code.labels).Distinct().ToDictionary((Label label) => label.GetHashCode(), (Label label) => label);
			CollectionExtensions.DoIf<LocalVariableInfo>((IEnumerable<LocalVariableInfo>)original.GetMethodBody().LocalVariables, (Func<LocalVariableInfo, bool>)((LocalVariableInfo local) => !Locals.ContainsKey(local.LocalIndex)), (Action<LocalVariableInfo>)delegate(LocalVariableInfo local)
			{
				Locals.Add(local.LocalIndex, local);
			});
			Instructions.ForEach(delegate(CodeInstruction code)
			{
				TrySetLocal(code, code);
			});
		}

		public Label DeclareLabel()
		{
			Label label = Generator.DefineLabel();
			Labels.Add(label.GetHashCode(), label);
			return label;
		}

		public LocalVariableInfo DeclareLocal(Type type, bool pinned = false)
		{
			LocalVariableInfo localVariableInfo = Generator.DeclareLocal(type, pinned);
			Locals.Add(localVariableInfo.LocalIndex, localVariableInfo);
			return localVariableInfo;
		}

		public LocalVariableInfo? TryGetLocal(int localIndex)
		{
			if (!Locals.TryGetValue(localIndex, out LocalVariableInfo value))
			{
				return null;
			}
			return value;
		}

		public LocalVariableInfo? TryGetLocal(CodeInstruction codeWithLocal)
		{
			if (!CodeInstructionExtensions.IsLdloc(codeWithLocal, (LocalBuilder)null) && !CodeInstructionExtensions.IsStloc(codeWithLocal, (LocalBuilder)null))
			{
				return null;
			}
			return TryGetLocal(codeWithLocal.LocalIndex());
		}

		public LocalVariableInfo GetLocal(int localIndex, string errorMessage = "No such local variable!")
		{
			return TryGetLocal(localIndex) ?? throw new Exception($"[libs.ILTools.GetLocal] [{localIndex}] | {errorMessage}");
		}

		public LocalVariableInfo GetLocal(CodeInstruction codeWithLocal, string errorMessage = "No such local variable!")
		{
			return TryGetLocal(codeWithLocal) ?? throw new Exception($"[libs.ILTools.GetLocal] [{codeWithLocal}] | {errorMessage}");
		}

		public LocalVariableInfo? TrySetLocal(CodeInstruction code, LocalVariableInfo local)
		{
			CodeInstruction val;
			if (CodeInstructionExtensions.IsLdloc(code, (LocalBuilder)null))
			{
				val = CodeInstructionPolyfills.LoadLocal(local, code.opcode == OpCodes.Ldloca || code.opcode == OpCodes.Ldloca_S);
			}
			else
			{
				if (!CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null))
				{
					return null;
				}
				val = CodeInstructionPolyfills.StoreLocal(local);
			}
			code.opcode = val.opcode;
			code.operand = val.operand;
			return local;
		}

		public LocalVariableInfo? TrySetLocal(CodeInstruction code, int localIndex)
		{
			LocalVariableInfo localVariableInfo = TryGetLocal(localIndex);
			if (localVariableInfo == null)
			{
				return null;
			}
			return TrySetLocal(code, localVariableInfo);
		}

		public LocalVariableInfo? TrySetLocal(CodeInstruction code, CodeInstruction codeWithLocal)
		{
			LocalVariableInfo localVariableInfo = TryGetLocal(codeWithLocal);
			if (localVariableInfo == null)
			{
				return null;
			}
			return TrySetLocal(code, localVariableInfo);
		}

		public LocalVariableInfo SetLocal(CodeInstruction code, LocalVariableInfo local, string errorMessage = "Could not set local!")
		{
			return TrySetLocal(code, local) ?? throw new Exception($"[libs.ILTools.SetLocal] [{code}, {local}] | {errorMessage}");
		}

		public LocalVariableInfo SetLocal(CodeInstruction code, int localIndex, string errorMessage = "Could not set local!")
		{
			return TrySetLocal(code, localIndex) ?? throw new Exception($"[libs.ILTools.SetLocal] [{code}, {localIndex}] | {errorMessage}");
		}

		public LocalVariableInfo SetLocal(CodeInstruction code, CodeInstruction codeWithLocal, string errorMessage = "Could not set local!")
		{
			return TrySetLocal(code, codeWithLocal) ?? throw new Exception($"[libs.ILTools.SetLocal] [{code}, {codeWithLocal}] | {errorMessage}");
		}

		public int? TryFindIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
		{
			index = (index ?? CurrentIndex) + offset + (reverse ? (-1) : 0);
			while (index >= 0 && index < Instructions.Count)
			{
				if (searchCondition(Instructions[index.Value], index.Value))
				{
					return index;
				}
				index += ((!reverse) ? 1 : (-1));
			}
			return null;
		}

		public int? TryFindIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
		{
			Func<CodeInstruction, bool> searchCondition2 = searchCondition;
			return TryFindIL((CodeInstruction code, int index) => searchCondition2(code), index, offset, reverse);
		}

		public int FindIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[libs.ILTools.FindIL] [{0}, {1}, {2} ({3})] | {4}", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
		}

		public int FindIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[libs.ILTools.FindIL] [{0}, {1}, {2} ({3})] | {4}", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
		}

		public int? TryGotoIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
		{
			index = TryFindIL(searchCondition, index, offset, reverse);
			CurrentIndex = index ?? CurrentIndex;
			return index;
		}

		public int? TryGotoIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
		{
			index = TryFindIL(searchCondition, index, offset, reverse);
			CurrentIndex = index ?? CurrentIndex;
			return index;
		}

		public int GotoIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return CurrentIndex = TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[libs.ILTools.GotoIL] [{0}, {1}, {2} ({3})] | {4}", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
		}

		public int GotoIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return CurrentIndex = TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[libs.ILTools.GotoIL] [{0}, {1}, {2} ({3})] | {4}", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
		}

		public int? TryFindIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1)
		{
			index = (index ?? CurrentIndex) + offset;
			if (index < leftBoundOffset || index > Instructions.Count - 1 + rightBoundOffset)
			{
				return null;
			}
			return index;
		}

		public int FindIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1, string errorMessage = "Out of bounds!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset) ?? throw new Exception($"[libs.ILTools.FindIndex] [{index + offset} ({index} + {offset}), {leftBoundOffset} (0 + {leftBoundOffset}), {Instructions.Count - 1 + rightBoundOffset} ({Instructions.Count - 1} + {rightBoundOffset})] | {errorMessage}");
		}

		public int? TryGotoIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1)
		{
			index = TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset);
			CurrentIndex = index ?? CurrentIndex;
			return index;
		}

		public int GotoIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1, string errorMessage = "Out of bounds!")
		{
			int valueOrDefault = index.GetValueOrDefault();
			if (!index.HasValue)
			{
				valueOrDefault = CurrentIndex;
				index = valueOrDefault;
			}
			return CurrentIndex = TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset) ?? throw new Exception($"[libs.ILTools.GotoIndex] [{index + offset} ({index} + {offset}), {leftBoundOffset} (0 + {leftBoundOffset}), {Instructions.Count - 1 + rightBoundOffset} ({Instructions.Count - 1} + {rightBoundOffset})] | {errorMessage}");
		}

		public List<CodeInstruction>? TryInsertIL(List<CodeInstruction> codeRange, int? index = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true)
		{
			index = TryFindIndex(index);
			if (!index.HasValue)
			{
				return null;
			}
			codeRange = ((I