Decompiled source of RuntimeIcons v0.3.0

BepInEx/plugins/RuntimeIcons.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CullFactory.Behaviours.API;
using HarmonyLib;
using JetBrains.Annotations;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLevelLoader;
using LethalLib.Modules;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RuntimeIcons.Components;
using RuntimeIcons.Config;
using RuntimeIcons.Dependency;
using RuntimeIcons.Dotnet.Backports;
using RuntimeIcons.Patches;
using RuntimeIcons.Utils;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Pool;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;
using VertexLibrary;
using VertexLibrary.Caches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("LethalCompanyModding")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.0")]
[assembly: AssemblyInformationalVersion("0.3.0+8f12d15a7fbe2308611ec23ce3f8ee21ec2a496c")]
[assembly: AssemblyProduct("RuntimeIcons")]
[assembly: AssemblyTitle("RuntimeIcons - Plugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RuntimeIcons
{
	[BepInPlugin("com.github.lethalcompanymodding.runtimeicons", "RuntimeIcons", "0.3.0")]
	[BepInDependency("com.github.lethalcompanymodding.vertexlibrary", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class RuntimeIcons : BaseUnityPlugin
	{
		public const string GUID = "com.github.lethalcompanymodding.runtimeicons";

		public const string NAME = "RuntimeIcons";

		public const string VERSION = "0.3.0";

		internal static readonly ISet<Hook> Hooks = new HashSet<Hook>();

		internal static readonly Harmony Harmony = new Harmony("com.github.lethalcompanymodding.runtimeicons");

		internal static ManualLogSource Log;

		internal static StageComponent RenderingStage;

		internal static Dictionary<string, OverrideHolder> OverrideMap = new Dictionary<string, OverrideHolder>(StringComparer.InvariantCultureIgnoreCase);

		public static Sprite LoadingSprite { get; private set; }

		public static Sprite LoadingSprite2 { get; private set; }

		public static Sprite WarningSprite { get; private set; }

		public static Sprite ErrorSprite { get; private set; }

		public static RuntimeIcons INSTANCE { get; private set; }

		private void Awake()
		{
			INSTANCE = this;
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				if (LobbyCompatibilityChecker.Enabled)
				{
					LobbyCompatibilityChecker.Init();
				}
				Log.LogInfo((object)"Initializing Configs");
				PluginConfig.Init();
				Log.LogInfo((object)"Loading Compute shader");
				if (LoadComputeShader())
				{
					Log.LogInfo((object)"Preparing Stage");
					SetStage();
					Log.LogInfo((object)"Loading Overrides");
					LoadOverrides();
					Log.LogInfo((object)"Loading Icons");
					LoadIcons();
					Log.LogInfo((object)"Patching Methods");
					StartOfRoundPatch.Init();
					Harmony.PatchAll();
					Log.LogInfo((object)"RuntimeIcons v0.3.0 Loaded!");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Exception while initializing: \n" + ex));
			}
		}

		private static bool LoadComputeShader()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			AssetBundle bundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "runtimeicons.unity3d"));
			return UnpremultiplyAndCountTransparent.LoadShaders(bundle);
		}

		internal static void VerboseMeshLog(LogType logLevel, Func<string> message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			LogLevel val;
			if ((int)logLevel <= 128)
			{
				if ((int)logLevel <= 8)
				{
					if ((int)logLevel != 2)
					{
						if ((int)logLevel != 4)
						{
							if ((int)logLevel != 8)
							{
								goto IL_00a6;
							}
							val = (LogLevel)4;
						}
						else
						{
							val = (LogLevel)2;
						}
					}
					else
					{
						val = (LogLevel)1;
					}
					goto IL_00a8;
				}
				if ((int)logLevel <= 32)
				{
					if ((int)logLevel == 16 || (int)logLevel == 32)
					{
						goto IL_0097;
					}
				}
				else if ((int)logLevel == 64 || (int)logLevel == 128)
				{
					goto IL_0097;
				}
			}
			else if ((int)logLevel <= 512)
			{
				if ((int)logLevel == 240)
				{
					goto IL_0097;
				}
				if ((int)logLevel == 256 || (int)logLevel == 512)
				{
					goto IL_009c;
				}
			}
			else if ((int)logLevel <= 2048)
			{
				if ((int)logLevel == 1024 || (int)logLevel == 2048)
				{
					goto IL_009c;
				}
			}
			else
			{
				if ((int)logLevel == 3840)
				{
					goto IL_009c;
				}
				if ((int)logLevel == 4094)
				{
					val = (LogLevel)63;
					goto IL_00a8;
				}
			}
			goto IL_00a6;
			IL_0097:
			val = (LogLevel)16;
			goto IL_00a8;
			IL_00a6:
			val = (LogLevel)0;
			goto IL_00a8;
			IL_009c:
			val = (LogLevel)32;
			goto IL_00a8;
			IL_00a8:
			LogLevel val2 = val;
			if ((val2 & PluginConfig.VerboseMeshLogs) != 0)
			{
				VerboseMeshLog(val2, message);
			}
		}

		internal static void VerboseMeshLog(LogLevel logLevel, Func<string> message)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Log.Log(logLevel, (object)message());
		}

		internal static void VerboseRenderingLog(LogLevel logLevel, string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if ((logLevel & PluginConfig.VerboseRenderingLogs) != 0)
			{
				Log.Log(logLevel, (object)message);
			}
		}

		private void SetStage()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Expected O, but got Unknown
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			RenderingStage = StageComponent.CreateStage((HideFlags)61, LayerMask.GetMask(new string[13]
			{
				"Default", "Player", "Water", "Props", "Room", "InteractableObject", "Foliage", "PhysicsObject", "Enemies", "PlayerRagdoll",
				"MapHazards", "MiscLevelGeometry", "Terrain"
			}), "RuntimeIcons.Stage");
			Object.DontDestroyOnLoad((Object)(object)((Component)RenderingStage).gameObject);
			((Component)RenderingStage).gameObject.transform.position = new Vector3(0f, 1000f, 1000f);
			RenderingStage.Resolution = new Vector2Int(256, 256);
			RenderingStage.MarginPixels = new Vector2(32f, 32f);
			GameObject val = new GameObject("SpotLight 1")
			{
				hideFlags = ((Object)this).hideFlags,
				layer = 1
			};
			val.transform.parent = RenderingStage.LightTransform;
			val.transform.localPosition = new Vector3(0f, 3f, 0f);
			val.transform.rotation = Quaternion.LookRotation(Vector3.down);
			GameObject val2 = val;
			Light val3 = val2.AddComponent<Light>();
			val3.type = (LightType)0;
			val3.shape = (LightShape)0;
			val3.color = Color.white;
			val3.colorTemperature = 6901f;
			val3.useColorTemperature = true;
			val3.shadows = (LightShadows)2;
			val3.spotAngle = 50f;
			val3.innerSpotAngle = 21.8f;
			val3.range = 7.11f;
			HDAdditionalLightData val4 = val2.AddComponent<HDAdditionalLightData>();
			val4.affectDiffuse = true;
			val4.affectSpecular = true;
			val4.affectsVolumetric = true;
			val4.applyRangeAttenuation = true;
			val4.color = Color.white;
			val4.colorShadow = true;
			val4.shadowDimmer = 0.8f;
			((ScalableSettingValue<int>)(object)val4.shadowResolution).@override = 1024;
			val4.customSpotLightShadowCone = 30f;
			val4.distance = 1.5E+11f;
			val4.fadeDistance = 10000f;
			val4.innerSpotPercent = 82.7f;
			val4.intensity = 75f;
			GameObject val5 = new GameObject("SpotLight 2")
			{
				hideFlags = ((Object)this).hideFlags,
				layer = 1
			};
			val5.transform.parent = RenderingStage.LightTransform;
			val5.transform.localPosition = new Vector3(-2.7f, 0f, -2.7f);
			val5.transform.rotation = Quaternion.Euler(0f, 45f, 0f);
			GameObject val6 = val5;
			Light val7 = val6.AddComponent<Light>();
			val7.type = (LightType)0;
			val7.shape = (LightShape)0;
			val7.color = Color.white;
			val7.colorTemperature = 6901f;
			val7.useColorTemperature = true;
			val7.shadows = (LightShadows)2;
			val7.spotAngle = 50f;
			val7.innerSpotAngle = 21.8f;
			val7.range = 7.11f;
			HDAdditionalLightData val8 = val6.AddComponent<HDAdditionalLightData>();
			val8.affectDiffuse = true;
			val8.affectSpecular = true;
			val8.affectsVolumetric = true;
			val8.applyRangeAttenuation = true;
			val8.color = Color.white;
			val8.colorShadow = true;
			val8.shadowDimmer = 0.6f;
			((ScalableSettingValue<int>)(object)val8.shadowResolution).@override = 1024;
			val8.customSpotLightShadowCone = 30f;
			val8.distance = 1.5E+11f;
			val8.fadeDistance = 10000f;
			val8.innerSpotPercent = 82.7f;
			val8.intensity = 50f;
			val8.shapeRadius = 0.5f;
			GameObject val9 = new GameObject("SpotLight 3")
			{
				hideFlags = ((Object)this).hideFlags,
				layer = 1
			};
			val9.transform.parent = RenderingStage.LightTransform;
			val9.transform.localPosition = new Vector3(2.7f, 0f, -2.7f);
			val9.transform.rotation = Quaternion.Euler(0f, -45f, 0f);
			GameObject val10 = val9;
			Light val11 = val10.AddComponent<Light>();
			val11.type = (LightType)0;
			val11.shape = (LightShape)0;
			val11.color = Color.white;
			val11.colorTemperature = 6901f;
			val11.useColorTemperature = true;
			val11.shadows = (LightShadows)2;
			val11.spotAngle = 50f;
			val11.innerSpotAngle = 21.8f;
			val11.range = 7.11f;
			HDAdditionalLightData val12 = val10.AddComponent<HDAdditionalLightData>();
			val12.affectDiffuse = true;
			val12.affectSpecular = false;
			val12.affectsVolumetric = true;
			val12.applyRangeAttenuation = true;
			val12.color = Color.white;
			val12.colorShadow = true;
			val12.shadowDimmer = 0.4f;
			((ScalableSettingValue<int>)(object)val12.shadowResolution).@override = 1024;
			val12.customSpotLightShadowCone = 30f;
			val12.distance = 1.5E+11f;
			val12.fadeDistance = 10000f;
			val12.innerSpotPercent = 82.7f;
			val12.intensity = 30f;
		}

		private void LoadIcons()
		{
			if (OverrideMap.TryGetValue("RuntimeIcons/Loading", out var value) && Object.op_Implicit((Object)(object)value.OverrideSprite))
			{
				LoadingSprite = value.OverrideSprite;
			}
			else
			{
				Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("LoadingSprite.png");
				LoadingSprite = SpriteUtils.CreateSprite(manifestResourceStream);
			}
			LoadingSprite2 = Object.Instantiate<Sprite>(LoadingSprite);
			Sprite loadingSprite = LoadingSprite;
			string name = (((Object)LoadingSprite.texture).name = "RuntimeIcons.Loading");
			((Object)loadingSprite).name = name;
			Sprite loadingSprite2 = LoadingSprite2;
			name = (((Object)LoadingSprite2.texture).name = "RuntimeIcons.Loading2");
			((Object)loadingSprite2).name = name;
			if (OverrideMap.TryGetValue("RuntimeIcons/Warning", out value) && Object.op_Implicit((Object)(object)value.OverrideSprite))
			{
				WarningSprite = value.OverrideSprite;
			}
			else
			{
				Stream manifestResourceStream2 = Assembly.GetExecutingAssembly().GetManifestResourceStream("WarningSprite.png");
				WarningSprite = SpriteUtils.CreateSprite(manifestResourceStream2);
			}
			Sprite warningSprite = WarningSprite;
			name = (((Object)WarningSprite.texture).name = "RuntimeIcons.Warning");
			((Object)warningSprite).name = name;
			if (OverrideMap.TryGetValue("RuntimeIcons/Error", out value) && Object.op_Implicit((Object)(object)value.OverrideSprite))
			{
				ErrorSprite = value.OverrideSprite;
			}
			else
			{
				Stream manifestResourceStream3 = Assembly.GetExecutingAssembly().GetManifestResourceStream("ErrorSprite.png");
				ErrorSprite = SpriteUtils.CreateSprite(manifestResourceStream3);
			}
			Sprite errorSprite = ErrorSprite;
			name = (((Object)ErrorSprite.texture).name = "RuntimeIcons.Error");
			((Object)errorSprite).name = name;
		}

		private static void LoadOverrides()
		{
			string text = Path.Combine(Paths.ConfigPath, "RuntimeIcons");
			if (Directory.Exists(text))
			{
				ProcessDirectory(text, "RuntimeIcons.Config");
			}
			foreach (string item in Directory.EnumerateDirectories(Paths.PluginPath).SelectMany((string d) => Directory.EnumerateDirectories(d, "RuntimeIcons")))
			{
				string fileName = Path.GetFileName(Path.GetDirectoryName(item));
				ProcessDirectory(item, fileName);
			}
			static void ProcessDirectory(string directory, string source)
			{
				//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f2: Expected O, but got Unknown
				//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0200: Expected O, but got Unknown
				//IL_029b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a2: Expected O, but got Unknown
				//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b0: Expected O, but got Unknown
				//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02df: Invalid comparison between Unknown and I4
				//IL_032a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0331: Expected O, but got Unknown
				//IL_0303: Unknown result type (might be due to invalid IL or missing references)
				string relativePath = Path.GetRelativePath(Paths.BepInExRootPath, directory);
				Log.LogDebug((object)("Searching " + relativePath));
				Dictionary<string, OverrideHolder> dictionary = new Dictionary<string, OverrideHolder>();
				foreach (string item2 in Directory.EnumerateFiles(directory, "*.png", SearchOption.AllDirectories))
				{
					string text3 = Path.GetRelativePath(directory, Path.ChangeExtension(item2, null)).Replace(Path.DirectorySeparatorChar, '/');
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item2);
					Log.LogDebug((object)("[" + source + "] Reading " + text3 + ".png"));
					byte[] data = File.ReadAllBytes(item2);
					Sprite val2 = SpriteUtils.CreateSprite(data);
					Texture2D texture = val2.texture;
					if (((Texture)texture).width != ((Texture)texture).height)
					{
						Object.Destroy((Object)(object)val2);
						Object.Destroy((Object)(object)texture);
						Log.LogError((object)("[" + source + "] Expected Icon " + fileNameWithoutExtension + ".png was not square!"));
					}
					else
					{
						string name = (((Object)val2.texture).name = "RuntimeIcons." + fileNameWithoutExtension);
						((Object)val2).name = name;
						OverrideHolder value4 = new OverrideHolder
						{
							OverrideSprite = val2,
							Source = source
						};
						dictionary[text3] = value4;
					}
				}
				foreach (string item3 in Directory.EnumerateFiles(directory, "*.json", SearchOption.AllDirectories))
				{
					string text5 = Path.GetRelativePath(directory, Path.ChangeExtension(item3, null)).Replace(Path.DirectorySeparatorChar, '/');
					Log.LogDebug((object)("[" + source + "] Reading " + text5 + ".json"));
					try
					{
						using StreamReader streamReader = File.OpenText(item3);
						JsonTextReader val3 = new JsonTextReader((TextReader)streamReader);
						try
						{
							JObject value5 = (JObject)JToken.ReadFrom((JsonReader)(object)val3);
							ProcessOverride(dictionary, text5, source, value5);
						}
						finally
						{
							((IDisposable)val3)?.Dispose();
						}
					}
					catch (Exception arg)
					{
						Log.LogError((object)$"[{source}] Exception reading {text5}.json\n{arg}");
					}
				}
				string path = Path.Combine(directory, "overrides.json");
				if (File.Exists(path))
				{
					Log.LogDebug((object)("[" + source + "] Found overrides.json"));
					try
					{
						using StreamReader streamReader2 = File.OpenText(path);
						JsonTextReader val4 = new JsonTextReader((TextReader)streamReader2);
						try
						{
							JObject val5 = (JObject)JToken.ReadFrom((JsonReader)(object)val4);
							foreach (JProperty item4 in val5.Properties())
							{
								string name2 = item4.Name;
								if ((int)item4.Value.Type != 1)
								{
									Log.LogWarning((object)$"[{source}] overrides.json Key {name2} has wrong type={item4.Value.Type} Expected={(object)(JTokenType)1}");
								}
								else
								{
									JObject value6 = (JObject)item4.Value;
									ProcessOverride(dictionary, name2, source, value6);
								}
							}
						}
						finally
						{
							((IDisposable)val4)?.Dispose();
						}
					}
					catch (Exception arg2)
					{
						Log.LogError((object)$"[{source}] Exception reading overrides.json\n{arg2}");
					}
				}
				Log.LogDebug((object)("[" + source + "] Applying overrides"));
				foreach (KeyValuePair<string, OverrideHolder> item5 in dictionary)
				{
					if (item5.Key.Contains('/') && (!OverrideMap.TryGetValue(item5.Key, out var value7) || value7.Priority <= item5.Value.Priority))
					{
						Log.LogDebug((object)$"[{source}] Overriding {item5.Key} with priority {item5.Value.Priority}");
						OverrideMap[item5.Key] = item5.Value;
					}
				}
			}
			static void ProcessOverride(Dictionary<string, OverrideHolder> localMap, string key, string source, JObject value)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Invalid comparison between Unknown and I4
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Invalid comparison between Unknown and I4
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Invalid comparison between Unknown and I4
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Invalid comparison between Unknown and I4
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				if (!localMap.TryGetValue(key, out var value2))
				{
					value2 = new OverrideHolder
					{
						Source = source
					};
					localMap[key] = value2;
				}
				JToken val = default(JToken);
				if (value.TryGetValue("priority", ref val) && (int)val.Type == 6)
				{
					value2.Priority = Extensions.Value<int>((IEnumerable<JToken>)val);
				}
				if (value.TryGetValue("item_rotation", ref val) && (int)val.Type == 2)
				{
					try
					{
						List<float> list = (List<float>)JsonConvert.DeserializeObject(((object)val).ToString(), typeof(List<float>));
						if (list != null && list.Count == 3)
						{
							value2.ItemRotation = new Vector3(list[0], list[1], list[2]);
						}
					}
					catch
					{
					}
				}
				if (value.TryGetValue("stage_rotation", ref val) && (int)val.Type == 2)
				{
					try
					{
						List<float> list2 = (List<float>)JsonConvert.DeserializeObject(((object)val).ToString(), typeof(List<float>));
						if (list2 != null && list2.Count == 3)
						{
							value2.StageRotation = new Vector3(list2[0], list2[1], list2[2]);
						}
					}
					catch
					{
					}
				}
				if (value.TryGetValue("icon_path", ref val) && (int)val.Type == 8)
				{
					string text2 = Extensions.Value<string>((IEnumerable<JToken>)val).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).ToLower();
					if (localMap.TryGetValue(text2, out var value3))
					{
						if (Object.op_Implicit((Object)(object)value3.OverrideSprite))
						{
							value2.OverrideSprite = value3.OverrideSprite;
						}
						else
						{
							Log.LogWarning((object)("Key " + text2 + " is not a file in " + source));
						}
					}
					else
					{
						Log.LogWarning((object)("Key " + text2 + " does not exist in " + source));
					}
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.lethalcompanymodding.runtimeicons";

		public const string PLUGIN_NAME = "RuntimeIcons";

		public const string PLUGIN_VERSION = "0.3.0";
	}
}
namespace RuntimeIcons.Utils
{
	public static class HudUtils
	{
		public static void UpdateIconsInHUD(Item item)
		{
			if (!Object.op_Implicit((Object)(object)GameNetworkManager.Instance) || !Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				return;
			}
			GrabbableObject[] itemSlots = GameNetworkManager.Instance.localPlayerController.ItemSlots;
			Image[] itemSlotIcons = HUDManager.Instance.itemSlotIcons;
			for (int i = 0; i < itemSlots.Length && i < itemSlotIcons.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)itemSlots[i]) && !((Object)(object)itemSlots[i].itemProperties != (Object)(object)item))
				{
					itemSlotIcons[i].sprite = item.itemIcon;
				}
			}
		}
	}
	public class ItemCategory
	{
		internal static Item[] VanillaItems;

		internal static readonly Dictionary<Item, (string api, string modname)> ItemModMap = new Dictionary<Item, (string, string)>();

		private static readonly Regex ConfigFilterRegex = new Regex("[\\n\\t\\\\\\'\\[\\]]");

		public static string GetPathForItem(Item item)
		{
			(string, string) tagForItem = GetTagForItem(item);
			return GetPathForTag(tagForItem, item);
		}

		public static (string api, string modname) GetTagForItem(Item item)
		{
			if (!ItemModMap.TryGetValue(item, out (string, string) value))
			{
				return ("Unknown", "");
			}
			return value;
		}

		public static string GetPathForTag((string api, string modname) modTag, Item item)
		{
			string path = string.Join("_", item.itemName.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
			string path2 = string.Join("_", modTag.modname.Split(Path.GetInvalidPathChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
			return Path.Combine(modTag.api, path2, path);
		}

		public static string SanitizeForConfig(string input)
		{
			return ConfigFilterRegex.Replace(input, "").Trim();
		}
	}
	public static class SpriteUtils
	{
		public class SpriteInfo
		{
			public string Source { get; internal set; }
		}

		public static Sprite CreateSprite(Texture2D texture)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2((float)((Texture)texture).width / 2f, (float)((Texture)texture).height / 2f), 100f, 0u, (SpriteMeshType)0);
		}

		public static Sprite CreateSprite(byte[] data)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			ImageConversion.LoadImage(val, data);
			return CreateSprite(val);
		}

		public static Sprite CreateSprite(Stream stream)
		{
			byte[] data;
			using (BinaryReader binaryReader = new BinaryReader(stream))
			{
				int count = (int)stream.Length;
				data = binaryReader.ReadBytes(count);
			}
			return CreateSprite(data);
		}
	}
	internal static class UnpremultiplyAndCountTransparent
	{
		private static ComputeShader _unpremultiplyAndCountTransparentShader;

		private static int _initializeShaderHandle;

		private static int _unpremultiplyAndCountTransparentHandle;

		private static uint _unpremultiplyAndCountTransparentThreadWidth;

		private static uint _unpremultiplyAndCountTransparentThreadHeight;

		private static ComputeBuffer _transparentCountBuffer;

		private static Dictionary<int, uint> _transparentCounts = new Dictionary<int, uint>();

		private static int _currentTransparentCountID = 0;

		private static int _texturePropertyID;

		internal static bool LoadShaders(AssetBundle bundle)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			_unpremultiplyAndCountTransparentShader = bundle.LoadAsset<ComputeShader>("Assets/Shaders/UnpremultiplyAndCountTransparent.compute");
			if (!Object.op_Implicit((Object)(object)_unpremultiplyAndCountTransparentShader))
			{
				RuntimeIcons.Log.LogFatal((object)"Failed to load the compute shader.");
				return false;
			}
			_initializeShaderHandle = _unpremultiplyAndCountTransparentShader.FindKernel("Initialize");
			_unpremultiplyAndCountTransparentHandle = _unpremultiplyAndCountTransparentShader.FindKernel("UnpremultiplyAndCountTransparent");
			uint num = default(uint);
			_unpremultiplyAndCountTransparentShader.GetKernelThreadGroupSizes(_unpremultiplyAndCountTransparentHandle, ref _unpremultiplyAndCountTransparentThreadWidth, ref _unpremultiplyAndCountTransparentThreadHeight, ref num);
			_transparentCountBuffer = new ComputeBuffer(1, 4);
			_unpremultiplyAndCountTransparentShader.SetBuffer(_initializeShaderHandle, "TransparentCount", _transparentCountBuffer);
			_unpremultiplyAndCountTransparentShader.SetBuffer(_unpremultiplyAndCountTransparentHandle, "TransparentCount", _transparentCountBuffer);
			_texturePropertyID = Shader.PropertyToID("Texture");
			return true;
		}

		public static int Execute(CommandBuffer cmd, RenderTexture texture)
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_unpremultiplyAndCountTransparentShader == (Object)null)
			{
				RuntimeIcons.Log.LogError((object)"UnpremultiplyAndCountTransparent has been called before the shader was loaded.");
				return -1;
			}
			int num = (int)(((Texture)texture).width / _unpremultiplyAndCountTransparentThreadWidth);
			int num2 = (int)(((Texture)texture).height / _unpremultiplyAndCountTransparentThreadHeight);
			if (num * _unpremultiplyAndCountTransparentThreadWidth > ((Texture)texture).width || num2 * _unpremultiplyAndCountTransparentThreadHeight > ((Texture)texture).height)
			{
				RuntimeIcons.Log.LogError((object)$"Texture size must be a multiple of {_unpremultiplyAndCountTransparentThreadWidth}x{_unpremultiplyAndCountTransparentThreadHeight}: {((Texture)texture).width}x{((Texture)texture).height}");
				return -1;
			}
			cmd.DispatchCompute(_unpremultiplyAndCountTransparentShader, _initializeShaderHandle, 1, 1, 1);
			cmd.SetComputeTextureParam(_unpremultiplyAndCountTransparentShader, _unpremultiplyAndCountTransparentHandle, _texturePropertyID, RenderTargetIdentifier.op_Implicit((Texture)(object)texture));
			cmd.DispatchCompute(_unpremultiplyAndCountTransparentShader, _unpremultiplyAndCountTransparentHandle, num, num2, 1);
			int countID = _currentTransparentCountID++;
			cmd.RequestAsyncReadback(_transparentCountBuffer, (Action<AsyncGPUReadbackRequest>)delegate(AsyncGPUReadbackRequest r)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				_transparentCounts[countID] = ((AsyncGPUReadbackRequest)(ref r)).GetData<uint>(0)[0];
			});
			return countID;
		}

		public static bool TryGetTransparentCount(int id, out uint count)
		{
			count = uint.MaxValue;
			if (id == -1)
			{
				return true;
			}
			if (_transparentCounts.Remove(id, out count))
			{
				return true;
			}
			return false;
		}
	}
}
namespace RuntimeIcons.Patches
{
	[HarmonyPatch]
	public static class GrabbableObjectPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		private static void AfterStart(GrabbableObject __instance)
		{
			RuntimeIcons.RenderingStage.CameraQueue.EnqueueObject(__instance, RuntimeIcons.WarningSprite, 2L);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GrabbableObject), "EquipItem")]
		private static void OnGrab(GrabbableObject __instance)
		{
			if (!((Object)(object)__instance.playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController) && !((Object)(object)__instance.itemProperties.itemIcon != (Object)(object)RuntimeIcons.WarningSprite))
			{
				RuntimeIcons.Log.LogInfo((object)("Attempting to refresh BrokenIcon for " + __instance.itemProperties.itemName + "!"));
				__instance.itemProperties.itemIcon = null;
				RuntimeIcons.RenderingStage.CameraQueue.EnqueueObject(__instance, RuntimeIcons.ErrorSprite, 0L);
			}
		}
	}
	[HarmonyPatch(typeof(HDRenderPipeline))]
	internal static class HDRenderPipelinePatch
	{
		internal static Action<ScriptableRenderContext, Camera> beginCameraRendering;

		[HarmonyTranspiler]
		[HarmonyPatch("Render", new Type[]
		{
			typeof(ScriptableRenderContext),
			typeof(List<Camera>)
		})]
		private static IEnumerable<CodeInstruction> AddCameraRenderHook(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction insn) => CodeInstructionExtensions.IsLdloc(insn, (LocalBuilder)null)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction insn) => CodeInstructionExtensions.IsLdloc(insn, (LocalBuilder)null)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)typeof(List<RenderRequest>).GetMethod("get_Item", new Type[1] { typeof(int) }), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction insn) => insn.opcode == OpCodes.Stloc || insn.opcode == OpCodes.Stloc_S), (string)null)
			});
			if (val.IsInvalid)
			{
				RuntimeIcons.Log.LogError((object)"Failed to hook into HDRP to render icons with transparency.");
				RuntimeIcons.Log.LogError((object)"RuntimeIcons will not function correctly.");
				return instructions;
			}
			CodeInstruction val2 = new CodeInstruction((val.Instruction.opcode == OpCodes.Stloc_S) ? OpCodes.Ldloc_S : OpCodes.Ldloc, val.Instruction.operand);
			val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(val2),
				new CodeInstruction(OpCodes.Ldarg_1, (object)null),
				new CodeInstruction(OpCodes.Call, (object)typeof(HDRenderPipelinePatch).GetMethod("BeginCameraRenderingHook", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(RenderRequest),
					typeof(ScriptableRenderContext)
				}, null))
			});
			return val.Instructions();
		}

		private static void BeginCameraRenderingHook(RenderRequest request, ScriptableRenderContext context)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			beginCameraRendering?.Invoke(context, request.hdCamera.camera);
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	internal static class MenuManagerPatch
	{
		private static bool _runOnce;

		[HarmonyFinalizer]
		[HarmonyPatch("Start")]
		private static void OnStart(MenuManager __instance)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (_runOnce)
			{
				return;
			}
			_runOnce = true;
			try
			{
				GrabbableObject[] array = Resources.FindObjectsOfTypeAll<GrabbableObject>();
				RuntimeIcons.Log.LogInfo((object)$"Caching vertexes for {array.Length} items!");
				GrabbableObject[] array2 = array;
				foreach (GrabbableObject val in array2)
				{
					Transform transform = ((Component)val).transform;
					ExecutionOptions val2 = new ExecutionOptions();
					((ExecutionOptions)(ref val2)).CullingMask = RuntimeIcons.RenderingStage.CullingMask;
					((ExecutionOptions)(ref val2)).LogHandler = RuntimeIcons.VerboseMeshLog;
					((ExecutionOptions)(ref val2)).VertexCache = RuntimeIcons.RenderingStage.VertexCache;
					VertexesExtensions.CacheVertexes(transform, val2);
				}
			}
			catch (Exception arg)
			{
				RuntimeIcons.Log.LogFatal((object)$"Exception while caching items: {arg}");
			}
		}
	}
	[HarmonyPatch]
	public class StartOfRoundPatch
	{
		internal static void Init()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			RuntimeIcons.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(StartOfRound), "Awake", (Type[])null, (Type[])null), (Delegate)new Action<Action<StartOfRound>, StartOfRound>(PrepareItemCache)));
		}

		private static void PrepareItemCache(Action<StartOfRound> orig, StartOfRound __instance)
		{
			ItemCategory.ItemModMap.Clear();
			if (ItemCategory.VanillaItems == null)
			{
				ItemCategory.VanillaItems = __instance.allItemsList.itemsList.ToArray();
			}
			Item[] vanillaItems = ItemCategory.VanillaItems;
			foreach (Item key in vanillaItems)
			{
				ItemCategory.ItemModMap.TryAdd(key, ("Vanilla", ""));
			}
			orig(__instance);
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		private static void PopulateModdedCache(StartOfRound __instance)
		{
			if (LethalLibProxy.Enabled)
			{
				LethalLibProxy.GetModdedItems(in ItemCategory.ItemModMap);
			}
			if (LethalLevelLoaderProxy.Enabled)
			{
				LethalLevelLoaderProxy.GetModdedItems(in ItemCategory.ItemModMap);
			}
			foreach (Item items in __instance.allItemsList.itemsList)
			{
				ItemCategory.ItemModMap.TryAdd(items, ("Unknown", ""));
			}
		}
	}
}
namespace RuntimeIcons.Dotnet.Backports
{
	internal static class EnumerableHelpers
	{
		internal static void Reset<T>(ref T enumerator) where T : IEnumerator
		{
			enumerator.Reset();
		}

		internal static IEnumerator<T> GetEmptyEnumerator<T>()
		{
			return ((IEnumerable<T>)Array.Empty<T>()).GetEnumerator();
		}

		internal static T[] ToArray<T>(IEnumerable<T> source, out int length)
		{
			if (source is ICollection<T> collection)
			{
				int count = collection.Count;
				if (count != 0)
				{
					T[] array = new T[count];
					collection.CopyTo(array, 0);
					length = count;
					return array;
				}
			}
			else
			{
				using IEnumerator<T> enumerator = source.GetEnumerator();
				if (enumerator.MoveNext())
				{
					T[] array2 = new T[4]
					{
						enumerator.Current,
						default(T),
						default(T),
						default(T)
					};
					int num = 1;
					while (enumerator.MoveNext())
					{
						if (num == array2.Length)
						{
							int num2 = num << 1;
							if ((uint)num2 > 2147483591u)
							{
								num2 = ((2147483591 <= num) ? (num + 1) : 2147483591);
							}
							Array.Resize(ref array2, num2);
						}
						array2[num++] = enumerator.Current;
					}
					length = num;
					return array2;
				}
			}
			length = 0;
			return Array.Empty<T>();
		}
	}
	[DebuggerDisplay("Count = {Count}")]
	[DebuggerTypeProxy(typeof(PriorityQueueDebugView<, >))]
	public class PriorityQueue<TElement, TPriority>
	{
		[DebuggerDisplay("Count = {Count}")]
		[DebuggerTypeProxy(typeof(PriorityQueueDebugView<, >))]
		public sealed class UnorderedItemsCollection : IReadOnlyCollection<(TElement Element, TPriority Priority)>, IEnumerable<(TElement Element, TPriority Priority)>, IEnumerable, ICollection
		{
			public struct Enumerator : IEnumerator<(TElement Element, TPriority Priority)>, IEnumerator, IDisposable
			{
				private readonly PriorityQueue<TElement, TPriority> _queue;

				private readonly int _version;

				private int _index;

				private (TElement, TPriority) _current;

				public (TElement Element, TPriority Priority) Current => _current;

				object IEnumerator.Current => _current;

				internal Enumerator(PriorityQueue<TElement, TPriority> queue)
				{
					_queue = queue;
					_index = 0;
					_version = queue._version;
					_current = default((TElement, TPriority));
				}

				public void Dispose()
				{
				}

				public bool MoveNext()
				{
					PriorityQueue<TElement, TPriority> queue = _queue;
					if (_version == queue._version && (uint)_index < (uint)queue._size)
					{
						_current = queue._nodes[_index];
						_index++;
						return true;
					}
					return MoveNextRare();
				}

				private bool MoveNextRare()
				{
					if (_version != _queue._version)
					{
						throw new InvalidOperationException("Invalid enum version");
					}
					_index = _queue._size + 1;
					_current = default((TElement, TPriority));
					return false;
				}

				void IEnumerator.Reset()
				{
					if (_version != _queue._version)
					{
						throw new InvalidOperationException("Invalid enum version");
					}
					_index = 0;
					_current = default((TElement, TPriority));
				}
			}

			internal readonly PriorityQueue<TElement, TPriority> _queue;

			public int Count => _queue._size;

			object ICollection.SyncRoot => this;

			bool ICollection.IsSynchronized => false;

			internal UnorderedItemsCollection(PriorityQueue<TElement, TPriority> queue)
			{
				_queue = queue;
			}

			void ICollection.CopyTo(Array array, int index)
			{
				if (array == null)
				{
					throw new ArgumentNullException("array");
				}
				if (array.Rank != 1)
				{
					throw new ArgumentException("Multidimensional Arrays not supported", "array");
				}
				if (array.GetLowerBound(0) != 0)
				{
					throw new ArgumentException("Lower bound must be non-zero", "array");
				}
				if (index < 0 || index > array.Length)
				{
					throw new ArgumentOutOfRangeException("index", index, "must be less or equal array lenght");
				}
				if (array.Length - index < _queue._size)
				{
					throw new ArgumentException("Invalid lenght offset");
				}
				try
				{
					Array.Copy(_queue._nodes, 0, array, index, _queue._size);
				}
				catch (ArrayTypeMismatchException)
				{
					throw new ArgumentException("Incompativle array type", "array");
				}
			}

			public Enumerator GetEnumerator()
			{
				return new Enumerator(_queue);
			}

			IEnumerator<(TElement Element, TPriority Priority)> IEnumerable<(TElement, TPriority)>.GetEnumerator()
			{
				if (_queue.Count != 0)
				{
					return GetEnumerator();
				}
				return EnumerableHelpers.GetEmptyEnumerator<(TElement, TPriority)>();
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(TElement, TPriority)>)this).GetEnumerator();
			}
		}

		private (TElement Element, TPriority Priority)[] _nodes;

		private readonly IComparer<TPriority>? _comparer;

		private UnorderedItemsCollection? _unorderedItems;

		private int _size;

		private int _version;

		private const int Arity = 4;

		private const int Log2Arity = 2;

		public int Count => _size;

		public IComparer<TPriority> Comparer => _comparer ?? Comparer<TPriority>.Default;

		public UnorderedItemsCollection UnorderedItems => _unorderedItems ?? (_unorderedItems = new UnorderedItemsCollection(this));

		public PriorityQueue()
		{
			_nodes = Array.Empty<(TElement, TPriority)>();
			_comparer = InitializeComparer(null);
		}

		public PriorityQueue(int initialCapacity)
			: this(initialCapacity, (IComparer<TPriority>?)null)
		{
		}

		public PriorityQueue(IComparer<TPriority>? comparer)
		{
			_nodes = Array.Empty<(TElement, TPriority)>();
			_comparer = InitializeComparer(comparer);
		}

		public PriorityQueue(int initialCapacity, IComparer<TPriority>? comparer)
		{
			if (initialCapacity < 0)
			{
				throw new ArgumentOutOfRangeException("initialCapacity", initialCapacity, "must be positive");
			}
			_nodes = new(TElement, TPriority)[initialCapacity];
			_comparer = InitializeComparer(comparer);
		}

		public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items)
			: this(items, (IComparer<TPriority>?)null)
		{
		}

		public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items, IComparer<TPriority>? comparer)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			_nodes = EnumerableHelpers.ToArray(items, out _size);
			_comparer = InitializeComparer(comparer);
			if (_size > 1)
			{
				Heapify();
			}
		}

		public void Enqueue(TElement element, TPriority priority)
		{
			int size = _size;
			_version++;
			if (_nodes.Length == size)
			{
				Grow(size + 1);
			}
			_size = size + 1;
			if (_comparer == null)
			{
				MoveUpDefaultComparer((element, priority), size);
			}
			else
			{
				MoveUpCustomComparer((element, priority), size);
			}
		}

		public TElement Peek()
		{
			if (_size == 0)
			{
				throw new InvalidOperationException("Queue is Empty");
			}
			return _nodes[0].Element;
		}

		public TElement Dequeue()
		{
			if (_size == 0)
			{
				throw new InvalidOperationException("Queue is Empty");
			}
			TElement item = _nodes[0].Element;
			RemoveRootNode();
			return item;
		}

		public TElement DequeueEnqueue(TElement element, TPriority priority)
		{
			if (_size == 0)
			{
				throw new InvalidOperationException("Queue is Empty");
			}
			(TElement, TPriority) tuple = _nodes[0];
			if (_comparer == null)
			{
				if (Comparer<TPriority>.Default.Compare(priority, tuple.Item2) > 0)
				{
					MoveDownDefaultComparer((element, priority), 0);
				}
				else
				{
					_nodes[0] = (element, priority);
				}
			}
			else if (_comparer.Compare(priority, tuple.Item2) > 0)
			{
				MoveDownCustomComparer((element, priority), 0);
			}
			else
			{
				_nodes[0] = (element, priority);
			}
			_version++;
			return tuple.Item1;
		}

		public bool TryDequeue([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
		{
			if (_size != 0)
			{
				(element, priority) = _nodes[0];
				RemoveRootNode();
				return true;
			}
			element = default(TElement);
			priority = default(TPriority);
			return false;
		}

		public bool TryPeek([MaybeNullWhen(false)] out TElement element, [MaybeNullWhen(false)] out TPriority priority)
		{
			if (_size != 0)
			{
				(element, priority) = _nodes[0];
				return true;
			}
			element = default(TElement);
			priority = default(TPriority);
			return false;
		}

		public TElement EnqueueDequeue(TElement element, TPriority priority)
		{
			if (_size != 0)
			{
				(TElement, TPriority) tuple = _nodes[0];
				if (_comparer == null)
				{
					if (Comparer<TPriority>.Default.Compare(priority, tuple.Item2) > 0)
					{
						MoveDownDefaultComparer((element, priority), 0);
						_version++;
						return tuple.Item1;
					}
				}
				else if (_comparer.Compare(priority, tuple.Item2) > 0)
				{
					MoveDownCustomComparer((element, priority), 0);
					_version++;
					return tuple.Item1;
				}
			}
			return element;
		}

		public void EnqueueRange(IEnumerable<(TElement Element, TPriority Priority)> items)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			int num = 0;
			ICollection<(TElement, TPriority)> collection = items as ICollection<(TElement, TPriority)>;
			if (collection != null && (num = collection.Count) > _nodes.Length - _size)
			{
				Grow(checked(_size + num));
			}
			if (_size == 0)
			{
				if (collection != null)
				{
					collection.CopyTo(_nodes, 0);
					_size = num;
				}
				else
				{
					int num2 = 0;
					(TElement, TPriority)[] nodes = _nodes;
					foreach (var (item, item2) in items)
					{
						if (nodes.Length == num2)
						{
							Grow(num2 + 1);
							nodes = _nodes;
						}
						nodes[num2++] = (item, item2);
					}
					_size = num2;
				}
				_version++;
				if (_size > 1)
				{
					Heapify();
				}
				return;
			}
			foreach (var (element, priority) in items)
			{
				Enqueue(element, priority);
			}
		}

		public void EnqueueRange(IEnumerable<TElement> elements, TPriority priority)
		{
			if (elements == null)
			{
				throw new ArgumentNullException("elements");
			}
			int count;
			if (elements is ICollection<TElement> collection && (count = collection.Count) > _nodes.Length - _size)
			{
				Grow(checked(_size + count));
			}
			if (_size == 0)
			{
				int num = 0;
				(TElement, TPriority)[] nodes = _nodes;
				foreach (TElement element in elements)
				{
					if (nodes.Length == num)
					{
						Grow(num + 1);
						nodes = _nodes;
					}
					nodes[num++] = (element, priority);
				}
				_size = num;
				_version++;
				return;
			}
			foreach (TElement element2 in elements)
			{
				Enqueue(element2, priority);
			}
		}

		public bool Remove(TElement element, [MaybeNullWhen(false)] out TElement removedElement, [MaybeNullWhen(false)] out TPriority priority, IEqualityComparer<TElement>? equalityComparer = null)
		{
			int num = FindIndex(element, equalityComparer);
			if (num < 0)
			{
				removedElement = default(TElement);
				priority = default(TPriority);
				return false;
			}
			(TElement, TPriority)[] nodes = _nodes;
			(TElement, TPriority) tuple = nodes[num];
			removedElement = tuple.Item1;
			priority = tuple.Item2;
			int num2 = --_size;
			if (num < num2)
			{
				(TElement, TPriority) node = nodes[num2];
				if (_comparer == null)
				{
					if (Comparer<TPriority>.Default.Compare(node.Item2, priority) < 0)
					{
						MoveUpDefaultComparer(node, num);
					}
					else
					{
						MoveDownDefaultComparer(node, num);
					}
				}
				else if (_comparer.Compare(node.Item2, priority) < 0)
				{
					MoveUpCustomComparer(node, num);
				}
				else
				{
					MoveDownCustomComparer(node, num);
				}
			}
			nodes[num2] = default((TElement, TPriority));
			_version++;
			return true;
		}

		public void Clear()
		{
			if (RuntimeHelpers.IsReferenceOrContainsReferences<(TElement, TPriority)>())
			{
				Array.Clear(_nodes, 0, _size);
			}
			_size = 0;
			_version++;
		}

		public int EnsureCapacity(int capacity)
		{
			if (capacity < 0)
			{
				throw new ArgumentOutOfRangeException("capacity", capacity, "must be positive");
			}
			if (_nodes.Length < capacity)
			{
				Grow(capacity);
				_version++;
			}
			return _nodes.Length;
		}

		public void TrimExcess()
		{
			int num = (int)((double)_nodes.Length * 0.9);
			if (_size < num)
			{
				Array.Resize(ref _nodes, _size);
				_version++;
			}
		}

		private void Grow(int minCapacity)
		{
			int val = 2 * _nodes.Length;
			val = Math.Max(val, _nodes.Length + 4);
			if (val < minCapacity)
			{
				val = minCapacity;
			}
			Array.Resize(ref _nodes, val);
		}

		private void RemoveRootNode()
		{
			int num = --_size;
			_version++;
			if (num > 0)
			{
				(TElement, TPriority) node = _nodes[num];
				if (_comparer == null)
				{
					MoveDownDefaultComparer(node, 0);
				}
				else
				{
					MoveDownCustomComparer(node, 0);
				}
			}
			if (RuntimeHelpers.IsReferenceOrContainsReferences<(TElement, TPriority)>())
			{
				_nodes[num] = default((TElement, TPriority));
			}
		}

		private static int GetParentIndex(int index)
		{
			return index - 1 >> 2;
		}

		private static int GetFirstChildIndex(int index)
		{
			return (index << 2) + 1;
		}

		private void Heapify()
		{
			(TElement, TPriority)[] nodes = _nodes;
			int parentIndex = GetParentIndex(_size - 1);
			if (_comparer == null)
			{
				for (int num = parentIndex; num >= 0; num--)
				{
					MoveDownDefaultComparer(nodes[num], num);
				}
			}
			else
			{
				for (int num2 = parentIndex; num2 >= 0; num2--)
				{
					MoveDownCustomComparer(nodes[num2], num2);
				}
			}
		}

		private void MoveUpDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			(TElement, TPriority)[] nodes = _nodes;
			while (nodeIndex > 0)
			{
				int parentIndex = GetParentIndex(nodeIndex);
				(TElement, TPriority) tuple = nodes[parentIndex];
				if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) >= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = parentIndex;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveUpCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			IComparer<TPriority> comparer = _comparer;
			(TElement, TPriority)[] nodes = _nodes;
			while (nodeIndex > 0)
			{
				int parentIndex = GetParentIndex(nodeIndex);
				(TElement, TPriority) tuple = nodes[parentIndex];
				if (comparer.Compare(node.Priority, tuple.Item2) >= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = parentIndex;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveDownDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			(TElement, TPriority)[] nodes = _nodes;
			int size = _size;
			int num;
			while ((num = GetFirstChildIndex(nodeIndex)) < size)
			{
				(TElement, TPriority) tuple = nodes[num];
				int num2 = num;
				int num3 = Math.Min(num + 4, size);
				while (++num < num3)
				{
					(TElement, TPriority) tuple2 = nodes[num];
					if (Comparer<TPriority>.Default.Compare(tuple2.Item2, tuple.Item2) < 0)
					{
						tuple = tuple2;
						num2 = num;
					}
				}
				if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) <= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = num2;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveDownCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			IComparer<TPriority> comparer = _comparer;
			(TElement, TPriority)[] nodes = _nodes;
			int size = _size;
			int num;
			while ((num = GetFirstChildIndex(nodeIndex)) < size)
			{
				(TElement, TPriority) tuple = nodes[num];
				int num2 = num;
				int num3 = Math.Min(num + 4, size);
				while (++num < num3)
				{
					(TElement, TPriority) tuple2 = nodes[num];
					if (comparer.Compare(tuple2.Item2, tuple.Item2) < 0)
					{
						tuple = tuple2;
						num2 = num;
					}
				}
				if (comparer.Compare(node.Priority, tuple.Item2) <= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = num2;
			}
			nodes[nodeIndex] = node;
		}

		private int FindIndex(TElement element, IEqualityComparer<TElement>? equalityComparer)
		{
			if (equalityComparer == null)
			{
				equalityComparer = EqualityComparer<TElement>.Default;
			}
			ReadOnlySpan<(TElement, TPriority)> readOnlySpan = _nodes.AsSpan(0, _size);
			if (typeof(TElement).IsValueType && equalityComparer == EqualityComparer<TElement>.Default)
			{
				for (int i = 0; i < readOnlySpan.Length; i++)
				{
					if (EqualityComparer<TElement>.Default.Equals(element, readOnlySpan[i].Item1))
					{
						return i;
					}
				}
			}
			else
			{
				for (int j = 0; j < readOnlySpan.Length; j++)
				{
					if (equalityComparer.Equals(element, readOnlySpan[j].Item1))
					{
						return j;
					}
				}
			}
			return -1;
		}

		private static IComparer<TPriority>? InitializeComparer(IComparer<TPriority>? comparer)
		{
			if (typeof(TPriority).IsValueType)
			{
				if (comparer == Comparer<TPriority>.Default)
				{
					return null;
				}
				return comparer;
			}
			return comparer ?? Comparer<TPriority>.Default;
		}
	}
	internal sealed class PriorityQueueDebugView<TElement, TPriority>
	{
		private readonly PriorityQueue<TElement, TPriority> _queue;

		private readonly bool _sort;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public (TElement Element, TPriority Priority)[] Items
		{
			get
			{
				List<(TElement, TPriority)> list = new List<(TElement, TPriority)>(_queue.UnorderedItems);
				if (_sort)
				{
					list.Sort(((TElement Element, TPriority Priority) i1, (TElement Element, TPriority Priority) i2) => _queue.Comparer.Compare(i1.Priority, i2.Priority));
				}
				return list.ToArray();
			}
		}

		public PriorityQueueDebugView(PriorityQueue<TElement, TPriority> queue)
		{
			_queue = queue ?? throw new ArgumentNullException("queue");
			_sort = true;
		}

		public PriorityQueueDebugView(PriorityQueue<TElement, TPriority>.UnorderedItemsCollection collection)
		{
			_queue = collection?._queue ?? throw new ArgumentNullException("collection");
		}
	}
}
namespace RuntimeIcons.Dependency
{
	internal class CullFactoryCompatibility
	{
		public const string GUID = "com.fumiko.CullFactory";

		public const string VERSION = "1.4.0";

		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					if (Chainloader.PluginInfos.TryGetValue("com.fumiko.CullFactory", out var value) && value.Metadata.Version >= Version.Parse("1.4.0"))
					{
						_enabled = true;
					}
					else
					{
						_enabled = false;
					}
				}
				return _enabled.Value;
			}
		}

		public static void DisableCullingForCamera(Camera camera)
		{
			if (Enabled)
			{
				DisableCullingForCameraImpl(camera);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void DisableCullingForCameraImpl(Camera camera)
		{
			CameraCullingOptions val = ((Component)camera).gameObject.AddComponent<CameraCullingOptions>();
			val.disableCulling = true;
		}
	}
	public static class LethalConfigProxy
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c__7<T> where T : Enum
		{
			public static readonly <>c__7<T> <>9 = new <>c__7<T>();

			public static CanModifyDelegate <>9__7_0;

			public static CanModifyDelegate <>9__7_1;

			internal CanModifyResult <AddConfig>b__7_0()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return CanModifyResult.op_Implicit((ValueTuple<bool, string>)(true, null));
			}

			internal CanModifyResult <AddConfig>b__7_1()
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return CanModifyResult.op_Implicit((false, "THIS IS A FLAG TYPE ENUM, EDITING CURRENTLY NOT SUPPORTED!"));
			}
		}

		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig(ConfigEntry<string> entry, bool requiresRestart = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(entry, new TextInputFieldOptions
			{
				RequiresRestart = requiresRestart,
				Name = GetPrettyConfigName<string>(entry)
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig(ConfigEntry<bool> entry, bool requiresRestart = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(entry, new BoolCheckBoxOptions
			{
				RequiresRestart = requiresRestart,
				Name = GetPrettyConfigName<bool>(entry)
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig(ConfigEntry<float> entry, bool requiresRestart = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(entry, new FloatInputFieldOptions
			{
				RequiresRestart = requiresRestart,
				Name = GetPrettyConfigName<float>(entry)
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig(ConfigEntry<int> entry, bool requiresRestart = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(entry, new IntInputFieldOptions
			{
				RequiresRestart = requiresRestart,
				Name = GetPrettyConfigName<int>(entry)
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig<T>(ConfigEntry<T> entry, bool requiresRestart = false) where T : Enum
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			object obj = <>c__7<T>.<>9__7_0;
			if (obj == null)
			{
				CanModifyDelegate val = () => CanModifyResult.op_Implicit((ValueTuple<bool, string>)(true, null));
				<>c__7<T>.<>9__7_0 = val;
				obj = (object)val;
			}
			CanModifyDelegate canModifyCallback = (CanModifyDelegate)obj;
			if (((ConfigEntryBase)entry).SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: true).Any())
			{
				object obj2 = <>c__7<T>.<>9__7_1;
				if (obj2 == null)
				{
					CanModifyDelegate val2 = () => CanModifyResult.op_Implicit((false, "THIS IS A FLAG TYPE ENUM, EDITING CURRENTLY NOT SUPPORTED!"));
					<>c__7<T>.<>9__7_1 = val2;
					obj2 = (object)val2;
				}
				canModifyCallback = (CanModifyDelegate)obj2;
			}
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem<T>(entry, new EnumDropDownOptions
			{
				RequiresRestart = requiresRestart,
				CanModifyCallback = canModifyCallback
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate
			{
				callback?.Invoke();
			}));
		}

		private static string GetPrettyConfigName<T>(ConfigEntry<T> entry)
		{
			return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(((ConfigEntryBase)entry).Definition.Key.Replace("_", " "));
		}
	}
	public static class LethalLevelLoaderProxy
	{
		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void GetModdedItems([NotNull] in Dictionary<Item, (string api, string modname)> items)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			RuntimeIcons.Log.LogInfo((object)"LethalLevelLoader found, reading PatchedContent.ExtendedItems");
			foreach (ExtendedItem extendedItem in PatchedContent.ExtendedItems)
			{
				if ((int)((ExtendedContent)extendedItem).ContentType != 0)
				{
					items.TryAdd(extendedItem.Item, ("LethalLevelLoader", ((ExtendedContent)extendedItem).ModName));
				}
			}
		}
	}
	public static class LethalLibProxy
	{
		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("evaisa.lethallib");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void GetModdedItems([NotNull] in Dictionary<Item, (string api, string modname)> items)
		{
			RuntimeIcons.Log.LogInfo((object)"LethalLib found, reading Items.scrapItems");
			foreach (ScrapItem scrapItem in Items.scrapItems)
			{
				items.TryAdd(scrapItem.item, ("LethalLib", scrapItem.modName));
			}
			foreach (PlainItem plainItem in Items.plainItems)
			{
				items.TryAdd(plainItem.item, ("LethalLib", plainItem.modName));
			}
			foreach (ShopItem shopItem in Items.shopItems)
			{
				items.TryAdd(shopItem.item, ("LethalLib", shopItem.modName));
			}
		}
	}
	public static class LobbyCompatibilityChecker
	{
		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void Init()
		{
			PluginHelper.RegisterPlugin("com.github.lethalcompanymodding.runtimeicons", Version.Parse("0.3.0"), (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
}
namespace RuntimeIcons.Config
{
	public class OverrideHolder
	{
		public string Source { get; internal set; } = "RuntimeIcons";


		public Sprite OverrideSprite { get; internal set; }

		public int Priority { get; internal set; }

		public Vector3? ItemRotation { get; internal set; }

		public Vector3? StageRotation { get; internal set; }
	}
	internal static class PluginConfig
	{
		public enum ListBehaviour
		{
			None,
			BlackList,
			WhiteList
		}

		private static ConfigEntry<ListBehaviour> _itemListBehaviourConfig;

		private static ConfigEntry<string> _itemListConfig;

		private static ConfigEntry<float> _failPercentage;

		private static ConfigEntry<LogLevel> _verboseMeshLogs;

		private static ConfigEntry<LogLevel> _verboseRenderingLogs;

		private static ConfigEntry<bool> _dumpToCache;

		internal static LogLevel VerboseMeshLogs => _verboseMeshLogs.Value;

		internal static LogLevel VerboseRenderingLogs => _verboseRenderingLogs.Value;

		internal static bool DumpToCache => _dumpToCache.Value;

		internal static float TransparencyRatio => _failPercentage.Value;

		internal static ISet<string> ItemList { get; private set; }

		internal static ListBehaviour ItemListBehaviour => _itemListBehaviourConfig.Value;

		internal static void Init()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			ConfigFile config = ((BaseUnityPlugin)RuntimeIcons.INSTANCE).Config;
			_verboseMeshLogs = config.Bind<LogLevel>("Debug", "Verbose Mesh Logs", (LogLevel)0, "Print Extra logs!");
			_verboseRenderingLogs = config.Bind<LogLevel>("Debug", "Verbose Rendering Logs", (LogLevel)0, "Print Extra logs!");
			_dumpToCache = config.Bind<bool>("Debug", "Dump sprites to cache", false, "Save the generated sprites into the cache folder");
			_itemListBehaviourConfig = config.Bind<ListBehaviour>("Config", "List Behaviour", ListBehaviour.BlackList, "What mode to use to filter what items will get new icons");
			_itemListConfig = config.Bind<string>("Config", "Item List", "", "List of items to filter\nExample: Vanilla/Big bolt, Unknown/Body");
			_failPercentage = config.Bind<float>("Config", "Transparency Threshold", 0.98f, new ConfigDescription("Maximum percentage of transparent pixels to consider a valid image", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ParseBlacklist();
			_itemListConfig.SettingChanged += delegate
			{
				ParseBlacklist();
			};
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddConfig<LogLevel>(_verboseMeshLogs, requiresRestart: false);
				LethalConfigProxy.AddConfig<LogLevel>(_verboseRenderingLogs, requiresRestart: false);
				LethalConfigProxy.AddConfig(_dumpToCache);
				LethalConfigProxy.AddConfig(_itemListConfig);
				LethalConfigProxy.AddConfig<ListBehaviour>(_itemListBehaviourConfig);
				LethalConfigProxy.AddConfig(_failPercentage);
				LethalConfigProxy.AddButton("Debug", "Refresh Held Item", "Regenerate Sprite for held Item", "Refresh", delegate
				{
					StartOfRound instance = StartOfRound.Instance;
					if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.localPlayerController.currentlyHeldObjectServer))
					{
						GrabbableObject currentlyHeldObjectServer = instance.localPlayerController.currentlyHeldObjectServer;
						Sprite itemIcon = currentlyHeldObjectServer.itemProperties.itemIcon;
						currentlyHeldObjectServer.itemProperties.itemIcon = null;
						RuntimeIcons.RenderingStage.CameraQueue.EnqueueObject(currentlyHeldObjectServer, itemIcon, 0L);
					}
				});
			}
			CleanAndSave();
			RotationEditor.Init();
			static void ParseBlacklist()
			{
				string[] source = _itemListConfig.Value.Split(",");
				ItemList = (from s in source
					select s.Trim() into s
					where !Utility.IsNullOrWhiteSpace(s)
					select s).ToHashSet();
			}
		}

		internal static void CleanAndSave()
		{
			ConfigFile config = ((BaseUnityPlugin)RuntimeIcons.INSTANCE).Config;
			PropertyInfo propertyInfo = AccessTools.Property(((object)config).GetType(), "OrphanedEntries");
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(config, null);
			dictionary.Clear();
			config.Save();
		}
	}
	internal static class RotationEditor
	{
		internal static void Init()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			ConfigEntry<string> eulerAngles;
			if (LethalConfigProxy.Enabled)
			{
				ConfigFile val = new ConfigFile(Path.GetTempFileName(), false, MetadataHelper.GetMetadata((object)RuntimeIcons.INSTANCE));
				eulerAngles = val.Bind<string>("Rotation Calculator", "Euler Angles", "0,0,0", "The Euler angles representing this rotation");
				ConfigEntry<float> angle2 = val.Bind<float>("Rotation Calculator", "Angle", 0f, new ConfigDescription("rotation angle", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-360f, 360f), Array.Empty<object>()));
				LethalConfigProxy.AddConfig(eulerAngles);
				LethalConfigProxy.AddConfig(angle2);
				LethalConfigProxy.AddButton("Rotation Calculator", "Apply X Rotation", "translate current EulerAngles around world X Axis by Rotation amount", "X Rot", delegate
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					ApplyRotation(angle2.Value, Vector3.right);
				});
				LethalConfigProxy.AddButton("Rotation Calculator", "Apply Y Rotation", "translate current EulerAngles around world X Axis by Rotation amount", "Y Rot", delegate
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					ApplyRotation(angle2.Value, Vector3.up);
				});
				LethalConfigProxy.AddButton("Rotation Calculator", "Apply Z Rotation", "translate current EulerAngles around world X Axis by Rotation amount", "Z Rot", delegate
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					ApplyRotation(angle2.Value, Vector3.forward);
				});
			}
			void ApplyRotation(float angle, Vector3 axis)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				Vector3 zero = Vector3.zero;
				string[] array = eulerAngles.Value.Split(",");
				if (array.Length == 3 && float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
				{
					((Vector3)(ref zero))..ctor(result, result2, result3);
				}
				Quaternion val2 = Quaternion.Euler(zero);
				Quaternion val3 = Quaternion.AngleAxis(angle, axis);
				Quaternion val4 = val3 * val2;
				eulerAngles.Value = $"{WrapAroundAngle(((Quaternion)(ref val4)).eulerAngles.x)},{WrapAroundAngle(((Quaternion)(ref val4)).eulerAngles.y)},{WrapAroundAngle(((Quaternion)(ref val4)).eulerAngles.z)}";
			}
		}

		private static float WrapAroundAngle(float angle)
		{
			angle %= 360f;
			angle = (angle + 360f) % 360f;
			if (angle > 180f)
			{
				angle -= 360f;
			}
			angle = (float)Math.Round(angle, 2);
			return angle;
		}
	}
}
namespace RuntimeIcons.Components
{
	public class CameraQueueComponent : MonoBehaviour
	{
		internal readonly struct RenderingRequest
		{
			internal readonly GrabbableObject GrabbableObject;

			internal readonly Item Item;

			internal readonly Sprite ErrorSprite;

			internal readonly OverrideHolder OverrideHolder;

			internal readonly string ItemKey;

			internal bool HasIcon
			{
				get
				{
					bool flag = PluginConfig.ItemList.Contains(ItemKey);
					if (PluginConfig.ItemListBehaviour switch
					{
						PluginConfig.ListBehaviour.BlackList => flag, 
						PluginConfig.ListBehaviour.WhiteList => !flag, 
						_ => false, 
					})
					{
						return true;
					}
					if (!Object.op_Implicit((Object)(object)Item.itemIcon))
					{
						return false;
					}
					if ((Object)(object)Item.itemIcon == (Object)(object)RuntimeIcons.LoadingSprite)
					{
						return false;
					}
					if (((Object)Item.itemIcon).name == "ScrapItemIcon")
					{
						return false;
					}
					if (((Object)Item.itemIcon).name == "ScrapItemIcon2")
					{
						return false;
					}
					if (Object.op_Implicit((Object)(object)OverrideHolder?.OverrideSprite) && (Object)(object)Item.itemIcon != (Object)(object)OverrideHolder.OverrideSprite)
					{
						return false;
					}
					return true;
				}
			}

			internal RenderingRequest(GrabbableObject grabbableObject, Sprite errorSprite)
			{
				GrabbableObject = grabbableObject;
				Item = GrabbableObject.itemProperties;
				ErrorSprite = errorSprite;
				ItemKey = ItemCategory.GetPathForItem(grabbableObject.itemProperties).Replace(Path.DirectorySeparatorChar, '/');
				RuntimeIcons.OverrideMap.TryGetValue(ItemKey, out var value);
				OverrideHolder = value;
			}
		}

		private readonly struct RenderingInstance
		{
			internal readonly RenderingRequest Request;

			internal readonly StageComponent.StageSettings Settings;

			internal readonly Texture2D Texture;

			public RenderingInstance(RenderingRequest request, StageComponent.StageSettings settings, Texture2D texture)
			{
				Request = request;
				Settings = settings;
				Texture = texture;
			}
		}

		private class RenderingResult
		{
			private bool _fencePassed;

			internal readonly RenderingRequest Request;

			internal readonly Texture2D Texture;

			internal readonly GraphicsFence Fence;

			internal readonly int ComputeID;

			internal bool FencePassed
			{
				get
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					if (_fencePassed)
					{
						return true;
					}
					GraphicsFence fence = Fence;
					if (!((GraphicsFence)(ref fence)).passed)
					{
						return false;
					}
					_fencePassed = true;
					return true;
				}
			}

			public RenderingResult(RenderingRequest request, Texture2D texture, GraphicsFence fence, int computeID)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				Request = request;
				Texture = texture;
				Fence = fence;
				ComputeID = computeID;
				base..ctor();
			}
		}

		private readonly struct ThreadMemory
		{
			[CompilerGenerated]
			private readonly CameraQueueComponent <self>P;

			internal readonly EventWaitHandle WaitHandle;

			internal readonly ConcurrentQueue<StageComponent.StageSettings> ComputeQueue;

			internal readonly ConcurrentQueue<StageComponent.StageSettings> ReadyQueue;

			internal readonly ConcurrentQueue<(RenderingRequest request, float opaqueRatio)> DoneQueue;

			internal readonly Dictionary<Item, List<RenderingRequest>> AlternativeRequests;

			public ThreadMemory(CameraQueueComponent self)
			{
				<self>P = self;
				WaitHandle = new ManualResetEvent(initialState: false);
				ComputeQueue = new ConcurrentQueue<StageComponent.StageSettings>();
				ReadyQueue = new ConcurrentQueue<StageComponent.StageSettings>();
				DoneQueue = new ConcurrentQueue<(RenderingRequest, float)>();
				AlternativeRequests = new Dictionary<Item, List<RenderingRequest>>();
			}

			internal bool TryEnqueueRequest(RenderingRequest request)
			{
				Item item = request.Item;
				if (AlternativeRequests.TryGetValue(item, out var value))
				{
					value.Add(request);
					return false;
				}
				AlternativeRequests[item] = new List<RenderingRequest>();
				StageComponent.StageSettings stageSettings = new StageComponent.StageSettings(<self>P.Stage, request);
				if (stageSettings.StagedVertexes.Length == 0)
				{
					return false;
				}
				ComputeQueue.Enqueue(stageSettings);
				WaitHandle.Set();
				return true;
			}

			internal bool TryEnqueueRetry(Item itemType)
			{
				if (!AlternativeRequests.TryGetValue(itemType, out var value))
				{
					return false;
				}
				if (value.Count > 0)
				{
					RenderingRequest renderingRequest = value[0];
					value.RemoveAt(0);
					StageComponent.StageSettings stageSettings = new StageComponent.StageSettings(<self>P.Stage, renderingRequest);
					if (stageSettings.StagedVertexes.Length == 0)
					{
						return false;
					}
					ComputeQueue.Enqueue(stageSettings);
					WaitHandle.Set();
					return true;
				}
				AlternativeRequests.Remove(itemType, out var _);
				return false;
			}

			internal bool TryEnqueueDone(RenderingRequest request, float opaqueRatio)
			{
				AlternativeRequests.Remove(request.Item);
				DoneQueue.Enqueue((request, opaqueRatio));
				WaitHandle.Set();
				return true;
			}

			internal bool TryDequeueReady(out StageComponent.StageSettings settings)
			{
				return ReadyQueue.TryDequeue(out settings);
			}
		}

		private readonly global::RuntimeIcons.Dotnet.Backports.PriorityQueue<RenderingRequest, long> _renderingQueue = new global::RuntimeIcons.Dotnet.Backports.PriorityQueue<RenderingRequest, long>(50);

		private Thread _computingThread;

		private ThreadMemory _computingMemory;

		private readonly List<RenderingResult> _renderedItems = new List<RenderingResult>();

		internal Camera StageCamera;

		internal StageComponent Stage;

		private bool _isStaged;

		private RenderingInstance? _nextRender;

		private StageComponent.IsolateStageLights _isolatorHolder;

		private void Start()
		{
			_computingMemory = new ThreadMemory(this);
			_computingThread = new Thread(ComputeThread)
			{
				Name = "ComputeThread",
				IsBackground = true
			};
			_computingThread.Start();
			StageCamera = Stage.Camera;
			RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
			RenderPipelineManager.endCameraRendering += OnEndCameraRendering;
		}

		private void ComputeThread()
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			ConcurrentQueue<StageComponent.StageSettings> computeQueue = _computingMemory.ComputeQueue;
			ConcurrentQueue<(RenderingRequest, float)> doneQueue = _computingMemory.DoneQueue;
			ConcurrentQueue<StageComponent.StageSettings> readyQueue = _computingMemory.ReadyQueue;
			EventWaitHandle waitHandle = _computingMemory.WaitHandle;
			RuntimeIcons.Log.LogInfo((object)"Starting compute thread!");
			StageComponent.StageSettings stageSettings = null;
			while (true)
			{
				try
				{
					if (computeQueue.IsEmpty && doneQueue.IsEmpty)
					{
						waitHandle.Reset();
						waitHandle.WaitOne();
					}
					(RenderingRequest, float) result;
					while (doneQueue.TryDequeue(out result))
					{
						var (renderingRequest, _) = result;
						if (result.Item2 < PluginConfig.TransparencyRatio)
						{
							RuntimeIcons.Log.LogInfo((object)(renderingRequest.ItemKey + " now has a new icon"));
						}
						else
						{
							RuntimeIcons.Log.LogError((object)$"{renderingRequest.ItemKey} Generated {result.Item2 * 100f:.#}% Empty Sprite!");
						}
					}
					if (computeQueue.TryDequeue(out var result2))
					{
						stageSettings = result2;
					}
					if (stageSettings != null)
					{
						RenderingRequest targetRequest = stageSettings.TargetRequest;
						try
						{
							RuntimeIcons.VerboseRenderingLog((LogLevel)16, "Computing stage for " + targetRequest.ItemKey);
							var (val, val2) = Stage.CenterObjectOnPivot(stageSettings);
							RuntimeIcons.VerboseRenderingLog((LogLevel)32, $"Item: offset {val} rotation {val2}");
							Quaternion item = Stage.FindOptimalRotation(stageSettings).rotation;
							RuntimeIcons.VerboseRenderingLog((LogLevel)32, $"Stage: rotation {((Quaternion)(ref item)).eulerAngles}");
							var (val3, num) = Stage.ComputeCameraAngleAndFOV(stageSettings);
							RuntimeIcons.VerboseRenderingLog((LogLevel)32, $"Camera Offset: {val3}");
							RuntimeIcons.VerboseRenderingLog((LogLevel)32, string.Format("Camera {0}: {1}", stageSettings.CameraOrthographic ? "orthographicSize" : "field of view", num));
							readyQueue.Enqueue(stageSettings);
						}
						catch (Exception arg)
						{
							string itemKey = targetRequest.ItemKey;
							RuntimeIcons.Log.LogError((object)$"Error Computing {itemKey}:\n{arg}");
						}
						finally
						{
							stageSettings = null;
						}
					}
				}
				catch (Exception arg2)
				{
					if (stageSettings != null)
					{
						stageSettings.State = StageComponent.StageSettingsState.Failed;
						readyQueue.Enqueue(stageSettings);
					}
					RuntimeIcons.Log.LogError((object)$"Something went wrong computing stageSettings\n{arg2}");
				}
				Thread.Yield();
			}
		}

		public bool EnqueueObject(GrabbableObject grabbableObject, Sprite errorSprite = null, long delay = 0L)
		{
			if (!Object.op_Implicit((Object)(object)grabbableObject))
			{
				throw new ArgumentNullException("grabbableObject");
			}
			if (!Object.op_Implicit((Object)(object)errorSprite))
			{
				errorSprite = RuntimeIcons.ErrorSprite;
			}
			RenderingRequest element = new RenderingRequest(grabbableObject, errorSprite);
			string itemKey = element.ItemKey;
			if (element.HasIcon)
			{
				return false;
			}
			RuntimeIcons.Log.LogInfo((object)("Computing " + itemKey + " icon"));
			if (Object.op_Implicit((Object)(object)element.OverrideHolder?.OverrideSprite))
			{
				grabbableObject.itemProperties.itemIcon = element.OverrideHolder.OverrideSprite;
				HudUtils.UpdateIconsInHUD(grabbableObject.itemProperties);
				RuntimeIcons.Log.LogInfo((object)(itemKey + " now has a new icon from " + element.OverrideHolder.Source));
				return true;
			}
			grabbableObject.itemProperties.itemIcon = RuntimeIcons.LoadingSprite;
			HudUtils.UpdateIconsInHUD(grabbableObject.itemProperties);
			_renderingQueue.Enqueue(element, Time.frameCount + delay);
			return true;
		}

		private bool PullLastRender(RenderingResult render)
		{
			if (!render.FencePassed)
			{
				return false;
			}
			if (!UnpremultiplyAndCountTransparent.TryGetTransparentCount(render.ComputeID, out var count))
			{
				return false;
			}
			Texture2D texture = render.Texture;
			int num = ((Texture)texture).width * ((Texture)texture).height;
			float num2 = (float)count / (float)num;
			GrabbableObject grabbableObject = render.Request.GrabbableObject;
			string itemKey = render.Request.ItemKey;
			try
			{
				_computingMemory.TryEnqueueDone(render.Request, num2);
				if (num2 < PluginConfig.TransparencyRatio)
				{
					Sprite val = SpriteUtils.CreateSprite(texture);
					string name = (((Object)val.texture).name = "RuntimeIcons." + grabbableObject.itemProperties.itemName);
					((Object)val).name = name;
					grabbableObject.itemProperties.itemIcon = val;
				}
				else
				{
					grabbableObject.itemProperties.itemIcon = render.Request.ErrorSprite;
					Object.Destroy((Object)(object)texture);
				}
			}
			catch (Exception arg)
			{
				RuntimeIcons.Log.LogError((object)$"Error generating {itemKey}\n{arg}");
				grabbableObject.itemProperties.itemIcon = render.Request.ErrorSprite;
			}
			HudUtils.UpdateIconsInHUD(grabbableObject.itemProperties);
			return true;
		}

		private void PrepareNextRender()
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			_nextRender = null;
			int frameCount = Time.frameCount;
			RenderingRequest element;
			long priority;
			while (_renderingQueue.TryPeek(out element, out priority) && priority <= frameCount)
			{
				RenderingRequest request = _renderingQueue.Dequeue();
				if (Object.op_Implicit((Object)(object)request.GrabbableObject) && !request.GrabbableObject.isPocketed && !request.HasIcon)
				{
					_computingMemory.TryEnqueueRequest(request);
				}
			}
			StageComponent.StageSettings stageSettings = null;
			StageComponent.StageSettings settings;
			RenderingRequest targetRequest;
			while (_computingMemory.TryDequeueReady(out settings))
			{
				targetRequest = settings.TargetRequest;
				if (settings.State == StageComponent.StageSettingsState.Failed || !Object.op_Implicit((Object)(object)targetRequest.GrabbableObject) || targetRequest.GrabbableObject.isPocketed || targetRequest.HasIcon)
				{
					_computingMemory.TryEnqueueRetry(targetRequest.Item);
					continue;
				}
				stageSettings = settings;
				break;
			}
			if (stageSettings == null)
			{
				((Behaviour)StageCamera).enabled = false;
				return;
			}
			targetRequest = stageSettings.TargetRequest;
			RuntimeIcons.VerboseRenderingLog((LogLevel)32, targetRequest.ItemKey + " is the next render");
			RenderTexture targetTexture = StageCamera.targetTexture;
			Texture2D texture = new Texture2D(((Texture)targetTexture).width, ((Texture)targetTexture).height, targetTexture.graphicsFormat, 1, (TextureCreationFlags)4)
			{
				name = "RuntimeIcons." + targetRequest.GrabbableObject.itemProperties.itemName + "Texture",
				filterMode = (FilterMode)0
			};
			_nextRender = new RenderingInstance(targetRequest, stageSettings, texture);
			if (StageCamera.orthographic)
			{
				StageCamera.orthographicSize = stageSettings.CameraFOV;
			}
			else
			{
				StageCamera.fieldOfView = stageSettings.CameraFOV;
			}
			((Component)StageCamera).transform.localRotation = stageSettings.CameraRotation;
			((Behaviour)StageCamera).enabled = true;
		}

		private void Update()
		{
			if (_renderedItems.Count > 0)
			{
				RenderingResult render = _renderedItems[0];
				if (PullLastRender(render))
				{
					_renderedItems.RemoveAt(0);
				}
			}
			PrepareNextRender();
		}

		private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
		{
			CameraCleanup();
			if ((Object)(object)camera != (Object)(object)StageCamera)
			{
				return;
			}
			RenderingInstance? nextRender = _nextRender;
			if (!nextRender.HasValue)
			{
				return;
			}
			string itemKey = _nextRender.Value.Request.ItemKey;
			StageComponent.StageSettings settings = _nextRender.Value.Settings;
			if (!Object.op_Implicit((Object)(object)settings.TargetObject))
			{
				_nextRender = null;
				_computingMemory.TryEnqueueRetry(settings.TargetRequest.Item);
				return;
			}
			try
			{
				settings.TargetObject.itemProperties.itemIcon = RuntimeIcons.LoadingSprite2;
				RuntimeIcons.VerboseRenderingLog((LogLevel)16, "Setting stage for " + itemKey);
				Stage.SetStageFromSettings(_nextRender.Value.Settings);
				_isolatorHolder = new StageComponent.IsolateStageLights(((Component)settings.TargetObject).gameObject, Stage.LightGo);
				_isStaged = true;
			}
			catch (Exception arg)
			{
				RuntimeIcons.Log.LogError((object)$"Error Rendering {itemKey}\n{arg}");
			}
		}

		private void OnEndCameraRendering(ScriptableRenderContext context, Camera camera)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown resu