Decompiled source of RestlessDrawers v0.2.3

RestlessDrawers.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("RestlessDrawers")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.3.0")]
[assembly: AssemblyInformationalVersion("0.2.3+3c3a455f9531bd9dc73b5fcaf8deb3470ee9edc9")]
[assembly: AssemblyProduct("RestlessDrawers")]
[assembly: AssemblyTitle("RestlessDrawers")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 RestlessDrawers
{
	internal sealed class DrawerRow
	{
		public string Id = "";

		public string Prefab = "";

		public string Source = "";

		public string Name = "";

		public string Description = "";
	}
	internal static class DrawerBook
	{
		public static readonly DrawerRow[] Rows = new DrawerRow[4]
		{
			new DrawerRow
			{
				Id = "wooden",
				Prefab = "RestlessDrawerWood",
				Source = "piece_chest_wood",
				Name = "Wood drawer",
				Description = "A furniture chest. Same space as a wood chest."
			},
			new DrawerRow
			{
				Id = "personal",
				Prefab = "RestlessDrawerPersonal",
				Source = "piece_chest_private",
				Name = "Personal drawer",
				Description = "A furniture chest only you can open. Same space as a personal chest."
			},
			new DrawerRow
			{
				Id = "reinforced",
				Prefab = "RestlessDrawerReinforced",
				Source = "piece_chest",
				Name = "Reinforced drawer",
				Description = "A furniture chest. Same space as a reinforced chest."
			},
			new DrawerRow
			{
				Id = "blackmetal",
				Prefab = "RestlessDrawerBlackMetal",
				Source = "piece_chest_blackmetal",
				Name = "Black metal drawer",
				Description = "A furniture chest. Same space as a black metal chest."
			}
		};

		public static bool IsOurs(string? prefab)
		{
			string text = prefab ?? "";
			if (text.Length > 0)
			{
				return text.StartsWith("RestlessDrawer", StringComparison.Ordinal);
			}
			return false;
		}
	}
	public sealed class DrawerFace : MonoBehaviour
	{
		private const int Slots = 4;

		private const float IconSize = 0.14f;

		private readonly SpriteRenderer[] _faces = (SpriteRenderer[])(object)new SpriteRenderer[4];

		private string _stamp = "";

		private void Awake()
		{
			Ensure();
		}

		private void OnEnable()
		{
			Refresh();
		}

		public void Refresh()
		{
			Ensure();
			Container component = ((Component)this).GetComponent<Container>();
			List<Sprite> list = Top(((Object)(object)component != (Object)null) ? component.GetInventory() : null);
			string text = Signature(list);
			if (text == _stamp)
			{
				return;
			}
			_stamp = text;
			for (int i = 0; i < 4; i++)
			{
				SpriteRenderer val = _faces[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (i >= list.Count)
					{
						((Renderer)val).enabled = false;
						val.sprite = null;
					}
					else
					{
						val.sprite = list[i];
						((Renderer)val).enabled = (Object)(object)list[i] != (Object)null;
					}
				}
			}
		}

		private void Ensure()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)this).transform.Find("RestlessDrawerMesh");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
			Bounds val2 = (Bounds)(((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) ? component.sharedMesh.bounds : new Bounds(Vector3.zero, Vector3.one * 0.5f));
			float num = ((Bounds)(ref val2)).center.z + ((Bounds)(ref val2)).extents.z + 0.012f;
			float y = ((Bounds)(ref val2)).center.y;
			float num2 = Mathf.Min(((Bounds)(ref val2)).size.x * 0.72f, 0.56f);
			float num3 = ((Bounds)(ref val2)).center.x - num2 * 0.5f + num2 / 4f * 0.5f;
			for (int i = 0; i < 4; i++)
			{
				if (!((Object)(object)_faces[i] != (Object)null))
				{
					GameObject val3 = new GameObject("RestlessDrawerFace" + i)
					{
						layer = ((Component)this).gameObject.layer
					};
					val3.transform.SetParent(val, false);
					val3.transform.localPosition = new Vector3(num3 + (float)i * (num2 / 4f), y, num);
					val3.transform.localRotation = Quaternion.identity;
					val3.transform.localScale = Vector3.one;
					SpriteRenderer val4 = val3.AddComponent<SpriteRenderer>();
					val4.drawMode = (SpriteDrawMode)0;
					val4.color = Color.white;
					((Renderer)val4).enabled = false;
					Vector3 lossyScale = val.lossyScale;
					val3.transform.localScale = new Vector3(0.14f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.x)), 0.14f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.y)), 0.14f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.z)));
					_faces[i] = val4;
				}
			}
		}

		private static List<Sprite> Top(Inventory? inv)
		{
			List<Sprite> list = new List<Sprite>();
			if (inv == null)
			{
				return list;
			}
			Dictionary<string, (int, Sprite)> dictionary = new Dictionary<string, (int, Sprite)>();
			foreach (ItemData allItem in inv.GetAllItems())
			{
				if (allItem?.m_shared != null)
				{
					string name = allItem.m_shared.m_name;
					dictionary.TryGetValue(name, out var value);
					dictionary[name] = (value.Item1 + Mathf.Max(1, allItem.m_stack), allItem.GetIcon());
				}
			}
			List<(int, Sprite)> list2 = new List<(int, Sprite)>(dictionary.Values);
			list2.Sort(((int count, Sprite? icon) a, (int count, Sprite? icon) b) => b.count.CompareTo(a.count));
			foreach (var item in list2)
			{
				if (!((Object)(object)item.Item2 == (Object)null))
				{
					list.Add(item.Item2);
					if (list.Count >= 4)
					{
						break;
					}
				}
			}
			return list;
		}

		private static string Signature(List<Sprite> icons)
		{
			string text = icons.Count.ToString();
			foreach (Sprite icon in icons)
			{
				text = text + ":" + (((Object)(object)icon != (Object)null) ? ((Object)icon).name : "");
			}
			return text;
		}
	}
	internal static class DrawerGrid
	{
		[HarmonyPatch]
		private static class Patches
		{
			[HarmonyPrefix]
			[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
			private static bool SkipSupport(WearNTear __instance)
			{
				if ((Object)(object)((Component)__instance).GetComponent<DrawerFace>() == (Object)null)
				{
					return true;
				}
				__instance.m_support = 1000f;
				return false;
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(WearNTear), "HaveSupport")]
			private static void AlwaysSupported(WearNTear __instance, ref bool __result)
			{
				if ((Object)(object)((Component)__instance).GetComponent<DrawerFace>() != (Object)null)
				{
					__result = true;
				}
			}
		}

		public const float Cell = 0.94f;

		public const float Overlap = 0.01f;

		public static void Fit(Mesh mesh, out Vector3 scale, out Vector3 offset)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0068: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = mesh.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float num = 0.95f;
			scale = new Vector3(num / Mathf.Max(0.05f, size.x), num / Mathf.Max(0.05f, size.y), num / Mathf.Max(0.05f, size.z));
			Vector3 val = Vector3.Scale(((Bounds)(ref bounds)).center, scale);
			offset = new Vector3(0f - val.x, num * 0.5f - val.y, 0f - val.z);
		}

		public static void Dress(GameObject prefab)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			StripOldSnaps(prefab);
			float num = 0.47f;
			float[] array = new float[2] { 0f, 0.94f };
			foreach (float num2 in array)
			{
				float[] array2 = new float[2]
				{
					0f - num,
					num
				};
				foreach (float num3 in array2)
				{
					float[] array3 = new float[2]
					{
						0f - num,
						num
					};
					foreach (float num4 in array3)
					{
						string name = "snap_" + ((num2 > 0f) ? "t" : "b") + ((num3 < 0f) ? "l" : "r") + ((num4 < 0f) ? "b" : "f");
						AddSnap(prefab, name, new Vector3(num3, num2, num4));
					}
				}
			}
		}

		private static void StripOldSnaps(GameObject prefab)
		{
			for (int num = prefab.transform.childCount - 1; num >= 0; num--)
			{
				Transform child = prefab.transform.GetChild(num);
				bool flag = ((Object)child).name.StartsWith("snap", StringComparison.OrdinalIgnoreCase);
				bool flag2 = ((Component)child).tag == "snappoint";
				if (flag || flag2)
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
		}

		private static void AddSnap(GameObject prefab, string name, Vector3 local)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				tag = "snappoint"
			};
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = local;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
		}
	}
	internal static class DrawerMesh
	{
		private static readonly Dictionary<string, Mesh> Meshes = new Dictionary<string, Mesh>();

		private static readonly Dictionary<string, Texture2D> Albedos = new Dictionary<string, Texture2D>();

		private static readonly Dictionary<string, Texture2D> Surfaces = new Dictionary<string, Texture2D>();

		private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>();

		private static string? _folder;

		private static MethodInfo? _loadImage;

		private static bool _searched;

		public static string Folder()
		{
			if (_folder != null)
			{
				return _folder;
			}
			string[] array = PluginRoots();
			string[] array2 = array;
			foreach (string text in array2)
			{
				string dir = Path.Combine(text, "mesh");
				if (HasRcm(dir))
				{
					return Remember(dir);
				}
				if (HasRcm(text))
				{
					return Remember(text);
				}
			}
			_folder = Path.Combine((array.Length != 0) ? array[0] : ".", "mesh");
			Plugin.Log.LogWarning((object)("drawer mesh folder missing, looking in " + _folder));
			return _folder;
		}

		private static string[] PluginRoots()
		{
			List<string> list = new List<string>();
			Plugin instance = Plugin.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PluginInfo info = ((BaseUnityPlugin)instance).Info;
				obj = ((info != null) ? info.Location : null);
			}
			string text = (string)obj;
			if (!string.IsNullOrEmpty(text))
			{
				AddRoot(list, Path.GetDirectoryName(text));
			}
			string location = typeof(DrawerMesh).Assembly.Location;
			if (!string.IsNullOrEmpty(location))
			{
				AddRoot(list, Path.GetDirectoryName(location));
			}
			return list.ToArray();
		}

		private static void AddRoot(List<string> roots, string? root)
		{
			string text = root ?? "";
			if (text.Length == 0)
			{
				return;
			}
			foreach (string root2 in roots)
			{
				if (string.Equals(root2, text, StringComparison.OrdinalIgnoreCase))
				{
					return;
				}
			}
			roots.Add(text);
		}

		private static string Remember(string dir)
		{
			_folder = dir;
			Plugin.Log.LogInfo((object)("drawer mesh folder " + dir));
			return dir;
		}

		private static bool HasRcm(string dir)
		{
			if (Directory.Exists(dir))
			{
				return Directory.GetFiles(dir, "*.rcm").Length != 0;
			}
			return false;
		}

		public static Mesh? Mesh(string id)
		{
			if (Meshes.TryGetValue(id, out Mesh value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string path = Path.Combine(Folder(), id + ".rcm");
			if (!File.Exists(path))
			{
				Plugin.Log.LogWarning((object)("drawer mesh missing " + id));
				return null;
			}
			value = ReadRcm(File.ReadAllBytes(path), id);
			if ((Object)(object)value != (Object)null)
			{
				Meshes[id] = value;
			}
			return value;
		}

		public static Texture2D? Albedo(string id)
		{
			if (Albedos.TryGetValue(id, out Texture2D value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string path = Path.Combine(Folder(), id + ".png");
			if (!File.Exists(path))
			{
				Plugin.Log.LogWarning((object)("drawer albedo missing " + id));
				return null;
			}
			value = DecodePng(File.ReadAllBytes(path), id);
			if ((Object)(object)value != (Object)null)
			{
				Albedos[id] = value;
			}
			return value;
		}

		public static Texture2D? Surface(string id)
		{
			if (Surfaces.TryGetValue(id, out Texture2D value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string path = Path.Combine(Folder(), id + ".metal.png");
			if (!File.Exists(path))
			{
				Plugin.Log.LogWarning((object)("drawer surface missing " + id));
				return null;
			}
			value = DecodePng(File.ReadAllBytes(path), id + ".metal", linear: true);
			if ((Object)(object)value != (Object)null)
			{
				Surfaces[id] = value;
			}
			return value;
		}

		public static Sprite? Icon(string id)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (Icons.TryGetValue(id, out Sprite value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Stream manifestResourceStream = typeof(DrawerMesh).Assembly.GetManifestResourceStream("RestlessDrawers.Assets." + id + ".png");
			if (manifestResourceStream == null)
			{
				Plugin.Log.LogWarning((object)("drawer icon missing " + id));
				return null;
			}
			using (manifestResourceStream)
			{
				byte[] array = new byte[manifestResourceStream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = manifestResourceStream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
				Texture2D val = DecodePng(array, id);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)value).name = id;
				Icons[id] = value;
				return value;
			}
		}

		private static Mesh? ReadRcm(byte[] data, string name)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			if (data.Length < 12 || data[0] != 82 || data[1] != 67 || data[2] != 77 || (data[3] != 49 && data[3] != 50))
			{
				Plugin.Log.LogWarning((object)("drawer mesh bad header " + name));
				return null;
			}
			bool flag = data[3] == 49;
			int num = 4;
			int num2 = BitConverter.ToInt32(data, num);
			num += 4;
			int num3 = BitConverter.ToInt32(data, num);
			num += 4;
			if (num2 <= 0 || num3 <= 0 || num + num2 * 32 + num3 * 4 > data.Length)
			{
				Plugin.Log.LogWarning((object)("drawer mesh truncated " + name));
				return null;
			}
			Vector3[] array = (Vector3[])(object)new Vector3[num2];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num2];
			Vector2[] array3 = (Vector2[])(object)new Vector2[num2];
			for (int i = 0; i < num2; i++)
			{
				array[i] = new Vector3(BitConverter.ToSingle(data, num), BitConverter.ToSingle(data, num + 4), BitConverter.ToSingle(data, num + 8));
				array2[i] = new Vector3(BitConverter.ToSingle(data, num + 12), BitConverter.ToSingle(data, num + 16), BitConverter.ToSingle(data, num + 20));
				float num4 = BitConverter.ToSingle(data, num + 28);
				array3[i] = new Vector2(BitConverter.ToSingle(data, num + 24), flag ? (1f - num4) : num4);
				num += 32;
			}
			int[] array4 = new int[num3];
			for (int j = 0; j < num3; j++)
			{
				array4[j] = BitConverter.ToInt32(data, num);
				num += 4;
			}
			Mesh val = new Mesh
			{
				name = name,
				indexFormat = (IndexFormat)(num2 > 65000)
			};
			val.SetVertices(array);
			val.SetNormals(array2);
			val.SetUVs(0, array3);
			val.SetTriangles(array4, 0);
			val.RecalculateBounds();
			return val;
		}

		private static Texture2D? DecodePng(byte[] bytes, string name, bool linear = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Texture2D val = (linear ? new Texture2D(2, 2, (TextureFormat)4, true, true) : new Texture2D(2, 2, (TextureFormat)4, true));
			MethodInfo methodInfo = LoadImage();
			if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[2] { val, bytes }))
			{
				Object.Destroy((Object)(object)val);
				Plugin.Log.LogWarning((object)("drawer png decode failed " + name));
				return null;
			}
			((Object)val).name = name;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).anisoLevel = 4;
			val.Apply(true, false);
			return val;
		}

		private static MethodInfo? LoadImage()
		{
			if (_searched)
			{
				return _loadImage;
			}
			_searched = true;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType("UnityEngine.ImageConversion");
				if (!(type == null))
				{
					_loadImage = type.GetMethod("LoadImage", new Type[2]
					{
						typeof(Texture2D),
						typeof(byte[])
					});
					if (_loadImage != null)
					{
						return _loadImage;
					}
				}
			}
			return null;
		}
	}
	[HarmonyPatch]
	internal static class DrawerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "Load")]
		private static void AfterLoad(Container __instance)
		{
			Face(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "Save")]
		private static void AfterSave(Container __instance)
		{
			Face(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "OnContainerChanged")]
		private static void AfterChanged(Container __instance)
		{
			Face(__instance);
		}

		private static void Face(Container container)
		{
			if (!((Object)(object)container == (Object)null))
			{
				DrawerFace component = ((Component)container).GetComponent<DrawerFace>();
				if ((Object)(object)component != (Object)null)
				{
					component.Refresh();
				}
			}
		}
	}
	internal static class DrawerPieces
	{
		private static bool _added;

		public static void Load()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Add;
		}

		private static void Add()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= Add;
			if (_added)
			{
				return;
			}
			_added = true;
			int num = 0;
			DrawerRow[] rows = DrawerBook.Rows;
			foreach (DrawerRow drawerRow in rows)
			{
				if ((Object)(object)PrefabManager.Instance.GetPrefab(drawerRow.Source) == (Object)null)
				{
					Plugin.Log.LogInfo((object)("RestlessDrawers skipped " + drawerRow.Source + " (no vanilla prefab)."));
					continue;
				}
				GameObject val = PrefabManager.Instance.CreateClonedPrefab(drawerRow.Prefab, drawerRow.Source);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				DrawerVisual.Apply(val, drawerRow);
				Piece val2 = val.GetComponent<Piece>() ?? val.AddComponent<Piece>();
				Sprite icon = (val2.m_icon = DrawerMesh.Icon(drawerRow.Id) ?? val2.m_icon);
				val2.m_name = drawerRow.Name;
				val2.m_description = drawerRow.Description;
				val2.m_groundOnly = false;
				val2.m_groundPiece = false;
				val2.m_clipGround = false;
				SitAsFurniture(val);
				PieceConfig val3 = new PieceConfig
				{
					Name = drawerRow.Name,
					Description = drawerRow.Description,
					PieceTable = PieceTables.Hammer,
					Icon = icon
				};
				if ((Object)(object)val2.m_craftingStation != (Object)null)
				{
					val3.CraftingStation = ((Object)val2.m_craftingStation).name;
				}
				if (val2.m_resources != null)
				{
					Requirement[] resources = val2.m_resources;
					foreach (Requirement val4 in resources)
					{
						if (!((Object)(object)val4?.m_resItem == (Object)null) && val4.m_amount > 0)
						{
							val3.AddRequirement(((Object)val4.m_resItem).name, val4.m_amount, val4.m_recover);
						}
					}
				}
				PieceManager.Instance.AddPiece(new CustomPiece(val, true, val3));
				num++;
			}
			Plugin.Log.LogInfo((object)("RestlessDrawers added " + num + " drawers."));
		}

		private static void SitAsFurniture(GameObject prefab)
		{
			WearNTear component = prefab.GetComponent<WearNTear>();
			if (!((Object)(object)component == (Object)null))
			{
				component.m_noSupportWear = false;
				component.m_supports = true;
				AccessTools.Method(typeof(WearNTear), "SetupColliders", (Type[])null, (Type[])null)?.Invoke(component, null);
			}
		}
	}
	internal static class DrawerVisual
	{
		public const string ChildName = "RestlessDrawerMesh";

		public static void Apply(GameObject prefab, DrawerRow row)
		{
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = DrawerMesh.Mesh(row.Id);
			Texture2D albedo = DrawerMesh.Albedo(row.Id);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("RestlessDrawers: no custom model for " + row.Id));
				return;
			}
			Material mat = CopyLit(prefab, row.Source);
			LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			GameObject val2 = FindOrCreate(prefab, val);
			(val2.GetComponent<MeshFilter>() ?? val2.AddComponent<MeshFilter>()).sharedMesh = val;
			MeshRenderer val3 = val2.GetComponent<MeshRenderer>() ?? val2.AddComponent<MeshRenderer>();
			((Renderer)val3).enabled = true;
			Paint((Renderer)(object)val3, albedo, DrawerMesh.Surface(row.Id), mat);
			Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren2)
			{
				if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)val3) && ((val4 is MeshRenderer || val4 is SkinnedMeshRenderer) ? true : false))
				{
					val4.enabled = false;
				}
			}
			Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val5 in componentsInChildren3)
			{
				if (!((Object)(object)val5 == (Object)null) && !((Object)(object)((Component)val5).transform == (Object)(object)val2.transform))
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
			}
			BoxCollider obj = val2.GetComponent<BoxCollider>() ?? val2.AddComponent<BoxCollider>();
			Bounds bounds = val.bounds;
			obj.center = ((Bounds)(ref bounds)).center;
			obj.size = Vector3.Max(((Bounds)(ref bounds)).size, new Vector3(0.2f, 0.2f, 0.2f));
			((Collider)obj).enabled = true;
			if ((Object)(object)prefab.GetComponent<DrawerFace>() == (Object)null)
			{
				prefab.AddComponent<DrawerFace>();
			}
			DrawerGrid.Dress(prefab);
		}

		private static GameObject FindOrCreate(GameObject prefab, Mesh mesh)
		{
			//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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Transform val = prefab.transform.Find("RestlessDrawerMesh");
			DrawerGrid.Fit(mesh, out var scale, out var offset);
			if ((Object)(object)val != (Object)null)
			{
				val.SetParent(prefab.transform, false);
				val.localPosition = offset;
				val.localRotation = Quaternion.identity;
				val.localScale = scale;
				((Component)val).gameObject.layer = prefab.layer;
				((Component)val).gameObject.SetActive(true);
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("RestlessDrawerMesh")
			{
				layer = prefab.layer
			};
			val2.transform.SetParent(prefab.transform, false);
			val2.transform.localPosition = offset;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = scale;
			return val2;
		}

		private static void Paint(Renderer renderer, Texture2D? albedo, Texture2D? surface, Material? mat)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mat == (Object)null)
			{
				return;
			}
			mat.color = Color.white;
			SetColor(mat, "_Color", Color.white);
			SetColor(mat, "_BaseColor", Color.white);
			SetColor(mat, "_Tint", Color.white);
			MuteGlow(mat);
			if ((Object)(object)albedo != (Object)null)
			{
				if (mat.HasProperty("_MainTex"))
				{
					mat.SetTexture("_MainTex", (Texture)(object)albedo);
				}
				if (mat.HasProperty("_BaseMap"))
				{
					mat.SetTexture("_BaseMap", (Texture)(object)albedo);
				}
				if (mat.HasProperty("_Diffuse"))
				{
					mat.SetTexture("_Diffuse", (Texture)(object)albedo);
				}
			}
			if ((Object)(object)surface != (Object)null)
			{
				if (mat.HasProperty("_MetallicTex"))
				{
					mat.SetTexture("_MetallicTex", (Texture)(object)surface);
				}
				if (mat.HasProperty("_MetallicGlossMap"))
				{
					mat.SetTexture("_MetallicGlossMap", (Texture)(object)surface);
				}
				SetFloat(mat, "_Metallic", 1f);
				SetFloat(mat, "_MetallicAlphaGloss", 1f);
				SetFloat(mat, "_Glossiness", 1f);
				SetFloat(mat, "_Smoothness", 1f);
				mat.EnableKeyword("_METALLICGLOSSMAP");
			}
			else
			{
				SetFloat(mat, "_Metallic", 0f);
				SetFloat(mat, "_Glossiness", 0.12f);
				SetFloat(mat, "_Smoothness", 0.12f);
			}
			renderer.sharedMaterial = mat;
		}

		private static Material? CopyLit(GameObject prefab, string source)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			Material val = QuietMat(prefab) ?? QuietNamed(source) ?? QuietNamed("piece_chest_wood") ?? QuietNamed("piece_chest");
			if ((Object)(object)val != (Object)null)
			{
				return new Material(val);
			}
			string[] array = new string[2] { "Legacy Shaders/Diffuse", "Diffuse" };
			for (int i = 0; i < array.Length; i++)
			{
				Shader val2 = Shader.Find(array[i]);
				if ((Object)(object)val2 != (Object)null)
				{
					return new Material(val2);
				}
			}
			Plugin.Log.LogWarning((object)"drawer shader missing — leave vanilla look");
			return null;
		}

		private static Material? QuietNamed(string name)
		{
			PrefabManager instance = PrefabManager.Instance;
			GameObject val = ((instance != null) ? instance.GetPrefab(name) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return QuietMat(val);
		}

		private static Material? QuietMat(GameObject? prefab)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			Renderer val = null;
			float num = -1f;
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).transform).name == "RestlessDrawerMesh" || (!(val2 is MeshRenderer) && !(val2 is SkinnedMeshRenderer)) || SkipNode(((Component)val2).transform))
				{
					continue;
				}
				Material sharedMaterial = val2.sharedMaterial;
				if (!((Object)(object)((sharedMaterial != null) ? sharedMaterial.shader : null) == (Object)null) && Usable(sharedMaterial))
				{
					Bounds bounds = val2.bounds;
					float x = ((Bounds)(ref bounds)).size.x;
					bounds = val2.bounds;
					float num2 = x * ((Bounds)(ref bounds)).size.y;
					bounds = val2.bounds;
					float num3 = num2 * ((Bounds)(ref bounds)).size.z;
					if (!(num3 <= num))
					{
						num = num3;
						val = val2;
					}
				}
			}
			if ((Object)(object)((val != null) ? val.sharedMaterial : null) == (Object)null)
			{
				return null;
			}
			Plugin.Log.LogInfo((object)("drawer lit " + ((Object)val).name + " / " + ((Object)val.sharedMaterial).name + " / " + ((Object)val.sharedMaterial.shader).name));
			return val.sharedMaterial;
		}

		private static bool SkipNode(Transform node)
		{
			Transform val = node;
			while ((Object)(object)val != (Object)null)
			{
				string name = ((Object)val).name;
				if (Has(name, "fx") || Has(name, "spark") || Has(name, "glow") || Has(name, "ghost") || Has(name, "particle") || Has(name, "wisp") || Has(name, "snow") || Has(name, "ice") || Has(name, "winter") || Has(name, "stack") || Has(name, "pile") || Has(name, "cover") || Has(name, "overlay"))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static bool Usable(Material mat)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			string text = ((Object)mat).name + " " + ((Object)mat.shader).name;
			if (Has(text, "Hidden/") || Has(text, "Particle") || Has(text, "glow") || Has(text, "ghost") || Has(text, "snow") || Has(text, "stack") || Has(text, "pile") || Has(text, "wind") || Has(text, "vegetation") || Has(text, "tree"))
			{
				return false;
			}
			if (((Object)mat.shader).name == "Standard")
			{
				return false;
			}
			if (mat.IsKeywordEnabled("_EMISSION") || mat.IsKeywordEnabled("EMISSION"))
			{
				return false;
			}
			if (mat.HasProperty("_EmissionColor"))
			{
				Color color = mat.GetColor("_EmissionColor");
				if (((Color)(ref color)).maxColorComponent > 0.02f)
				{
					return false;
				}
			}
			return true;
		}

		private static void MuteGlow(Material mat)
		{
			//IL_0006: 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)
			SetColor(mat, "_EmissionColor", Color.black);
			SetColor(mat, "_EmissiveColor", Color.black);
			SetFloat(mat, "_EnableEmission", 0f);
			mat.DisableKeyword("_EMISSION");
			mat.DisableKeyword("EMISSION");
		}

		private static bool Has(string text, string token)
		{
			return text.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static void SetColor(Material mat, string prop, Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (mat.HasProperty(prop))
			{
				mat.SetColor(prop, color);
			}
		}

		private static void SetFloat(Material mat, string prop, float value)
		{
			if (mat.HasProperty(prop))
			{
				mat.SetFloat(prop, value);
			}
		}
	}
	[BepInPlugin("restless.drawers", "RestlessDrawers", "0.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("restless.core", "0.3.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "restless.drawers";

		public const string PluginName = "RestlessDrawers";

		public const string PluginVersion = "0.2.3";

		private Harmony? _harmony;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			DrawerPieces.Load();
			_harmony = new Harmony("restless.drawers");
			_harmony.PatchAll();
			Log.LogInfo((object)"RestlessDrawers 0.2.3 loaded.");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}