Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RuntimeIcons v0.3.3
BepInEx/plugins/RuntimeIcons.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
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.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.3")] [assembly: AssemblyInformationalVersion("0.3.3+0d6c8114f71aefa31a6571a562318d44dd640cfc")] [assembly: AssemblyProduct("RuntimeIcons")] [assembly: AssemblyTitle("RuntimeIcons - Plugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.3.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.3")] [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.3"; 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(typeof(HDRenderPipelinePatch)); Harmony.PatchAll(typeof(MenuManagerPatch)); Harmony.PatchAll(typeof(StartOfRoundPatch)); Harmony.PatchAll(typeof(GrabbableObjectPatch)); Log.LogInfo((object)"RuntimeIcons v0.3.3 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.3"; } } 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 _unpremultiplyAndCountTransparentHandle; private static uint _unpremultiplyAndCountTransparentThreadWidth; private static uint _unpremultiplyAndCountTransparentThreadHeight; private static ComputeBuffer _transparentCountBuffer; private static uint[] _transparentCountZeroes = new uint[1]; private static int _currentTransparentCountID = 0; private static readonly Dictionary<int, uint> _transparentCounts = new Dictionary<int, uint>(); private static int _texturePropertyID; internal static bool LoadShaders(AssetBundle bundle) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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; } _unpremultiplyAndCountTransparentHandle = _unpremultiplyAndCountTransparentShader.FindKernel("UnpremultiplyAndCountTransparent"); uint num = default(uint); _unpremultiplyAndCountTransparentShader.GetKernelThreadGroupSizes(_unpremultiplyAndCountTransparentHandle, ref _unpremultiplyAndCountTransparentThreadWidth, ref _unpremultiplyAndCountTransparentThreadHeight, ref num); _transparentCountBuffer = new ComputeBuffer(1, 4); _unpremultiplyAndCountTransparentShader.SetBuffer(_unpremultiplyAndCountTransparentHandle, "TransparentCount", _transparentCountBuffer); _texturePropertyID = Shader.PropertyToID("Texture"); return true; } public static int Execute(CommandBuffer cmd, RenderTexture texture) { //IL_00cb: 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.SetComputeTextureParam(_unpremultiplyAndCountTransparentShader, _unpremultiplyAndCountTransparentHandle, _texturePropertyID, RenderTargetIdentifier.op_Implicit((Texture)(object)texture)); cmd.SetBufferData(_transparentCountBuffer, (Array)_transparentCountZeroes); 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; internal static Action<ScriptableRenderContext, Camera> beforeRenderContextSubmit; [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 //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0279: 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)) }); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction insn) => insn.opcode == OpCodes.Ldarga || insn.opcode == OpCodes.Ldarga_S), (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(ScriptableRenderContext).GetMethod("Submit"), (string)null) }); if (val.IsInvalid) { RuntimeIcons.Log.LogError((object)"Failed to hook into HDRP before it submits its command buffer."); RuntimeIcons.Log.LogError((object)"RuntimeIcons will not function correctly."); return instructions; } val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(val2), new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Call, (object)typeof(HDRenderPipelinePatch).GetMethod("BeforeRenderContextSubmitHook", 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); } private static void BeforeRenderContextSubmitHook(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) beforeRenderContextSubmit?.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.3"), (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); } } internal struct IsolateStageLights { private List<Light> _disabledLights; private List<Light> _localLights; private Color? _ambientLight; public IsolateStageLights() { _disabledLights = new List<Light>(); _localLights = new List<Light>(); _ambientLight = null; } internal void Begin(GameObject[] stageObjects) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) End(); _ambientLight = RenderSettings.ambientLight; RenderSettings.ambientLight = Color.black; foreach (GameObject val in stageObjects) { _localLights.AddRange(val.GetComponentsInChildren<Light>()); } Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val2 in array) { if (((Behaviour)val2).enabled && !_localLights.Contains(val2)) { _disabledLights.Add(val2); ((Behaviour)val2).enabled = false; } } } internal void End() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (_ambientLight.HasValue) { RenderSettings.ambientLight = _ambientLight.Value; } _ambientLight = null; HDAdditionalLightData val = default(HDAdditionalLightData); foreach (Light disabledLight in _disabledLights) { ((Behaviour)disabledLight).enabled = true; if (((Component)disabledLight).TryGetComponent<HDAdditionalLightData>(ref val)) { val.UpdateBounds(); } } _disabledLights.Clear(); _localLights.Clear(); } } 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 IsolateStageLights _isolator = new IsolateStageLights(); private void Start() { _computingMemory = new ThreadMemory(this); _computingThread = new Thread(ComputeThread) { Name = "ComputeThread", IsBackground = true }; _computingThread.Start(); StageCamera = Stage.Camera; } private void OnEnable() { RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; HDRenderPipelinePatch.beforeRenderContextSubmit = (Action<ScriptableRenderContext, Camera>)Delegate.Combine(HDRenderPipelinePatch.beforeRenderContextSubmit, new Action<ScriptableRenderContext, Camera>(OnBeforeRenderContextSubmit)); } private void OnDisable() { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; HDRenderPipelinePatch.beforeRenderContextSubmit = (Action<ScriptableRenderContext, Camera>)Delegate.Remove(HDRenderPipelinePatch.beforeRenderContextSubmit, new Action<ScriptableRenderContext, Camera>(OnBeforeRenderContextSubmit)); } 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 ex) when (((ex is ThreadAbortException || ex is ThreadInterruptedException) ? 1 : 0) != 0) { RuntimeIcons.Log.LogDebug((object)"Compute thread is being aborted, exiting!"); break; } 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