Decompiled source of QuietCrafting v1.0.0

plugins/QuietCrafting/QuietCrafting.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("QuietCrafting")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Selective sound muting for Sun Haven.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("QuietCrafting")]
[assembly: AssemblyTitle("QuietCrafting")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 QuietCrafting
{
	internal static class ChatCommand
	{
		internal static bool Install(Harmony harmony)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.TypeByName("QFSW.QC.QuantumConsole")?.GetMethod("InvokeCommand", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(object))
			{
				Plugin.Warn("Compatible chat command handler not found; /sounds is unavailable.");
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ChatCommand), "BeforeInvoke", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		private static bool BeforeInvoke(object __instance, string __0, ref object? __result)
		{
			if (!SoundLogCommandText.Matches(__0))
			{
				return true;
			}
			__result = null;
			try
			{
				__instance.GetType().GetMethod("Deactivate", Type.EmptyTypes)?.Invoke(__instance, null);
				SoundLogWindow.Show();
			}
			catch (Exception arg)
			{
				Plugin.Warn($"Could not open /sounds: {arg}");
			}
			return false;
		}
	}
	internal sealed class ClipBlacklist
	{
		private readonly HashSet<string> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal int Count => names.Count;

		internal ClipBlacklist(string? text)
		{
			string[] array = (text ?? string.Empty).Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length != 0)
				{
					names.Add(text2);
				}
			}
		}

		internal bool Contains(string? name)
		{
			if (name != null)
			{
				return names.Contains(name);
			}
			return false;
		}

		internal bool SetEquals(ClipBlacklist other)
		{
			return names.SetEquals(other.names);
		}
	}
	internal static class DefaultSettings
	{
		internal const string MutedClips = "WoodcuttingTable2; ElvenCraftingTable1";

		internal const int Revision = 1;

		private const string LegacyPreset = "CraftingTable1; ElvenCraftingTable1";

		internal static string UpgradePreset(string current, int revision)
		{
			if (revision >= 1 || !new ClipBlacklist(current).SetEquals(new ClipBlacklist("CraftingTable1; ElvenCraftingTable1")))
			{
				return current;
			}
			return "WoodcuttingTable2; ElvenCraftingTable1";
		}
	}
	internal sealed class NativeSoundTheme : IDisposable
	{
		internal static readonly Color Ink = Color32.op_Implicit(new Color32((byte)63, (byte)36, (byte)25, byte.MaxValue));

		internal static readonly Color Cream = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)243, (byte)219, byte.MaxValue));

		internal static readonly Color Gold = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)224, (byte)104, byte.MaxValue));

		internal static readonly Color Brown = Color32.op_Implicit(new Color32((byte)111, (byte)72, (byte)50, byte.MaxValue));

		internal static readonly Color PaperColor = Color32.op_Implicit(new Color32((byte)197, (byte)174, (byte)126, byte.MaxValue));

		internal static readonly Color Red = Color32.op_Implicit(new Color32((byte)158, (byte)39, (byte)32, byte.MaxValue));

		internal readonly SoundMenuArt Art = new SoundMenuArt();

		internal readonly Sprite Frame;

		internal readonly Sprite Paper;

		internal readonly Sprite RedButton;

		internal readonly Sprite ScrollTrack;

		internal readonly Sprite ScrollHandle;

		private readonly Sprite? pressedButton;

		private readonly Sprite? hoverButton;

		private readonly TMP_FontAsset? font;

		private readonly TMP_FontAsset? ownedFont;

		private readonly Material? ownedFontMaterial;

		private readonly Material? plainTextMaterial;

		internal NativeSoundTheme()
		{
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Expected O, but got Unknown
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			Sprite[] sprites = Resources.FindObjectsOfTypeAll<Sprite>();
			Frame = Art.Window;
			Paper = Art.Paper;
			RedButton = Find("popup_button_confirm_normal-hover-push_0") ?? Art.Window;
			pressedButton = Find("popup_button_confirm_normal-hover-push_2");
			hoverButton = Find("popup_button_confirm_normal-hover-push_1");
			ScrollTrack = Find("store_scrollbar_track") ?? Art.Field;
			ScrollHandle = Find("scrollbar_knob") ?? Art.ActiveTab;
			TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			font = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset candidate) => Object.op_Implicit((Object)(object)candidate) && ((Object)candidate).name.IndexOf("GurajadaOutlined", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset candidate) => Object.op_Implicit((Object)(object)candidate) && ((Object)candidate).name.IndexOf("Gurajada", StringComparison.OrdinalIgnoreCase) >= 0)) ?? TMP_Settings.defaultFontAsset;
			if (Object.op_Implicit((Object)(object)font) && ((Object)font).name.IndexOf("Gurajada", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				ownedFont = Object.Instantiate<TMP_FontAsset>(font);
				((Object)ownedFont).name = "QuietCrafting.MenuFont";
				Texture2D[] atlasTextures = font.atlasTextures;
				Texture2D[] array = (Texture2D[])(object)new Texture2D[atlasTextures.Length];
				for (int num = 0; num < atlasTextures.Length; num++)
				{
					if (Object.op_Implicit((Object)(object)atlasTextures[num]))
					{
						array[num] = Object.Instantiate<Texture2D>(atlasTextures[num]);
						((Object)array[num]).name = $"QuietCrafting.MenuFont Atlas {num}";
						if ((Object)(object)array[num] == (Object)(object)atlasTextures[num])
						{
							throw new InvalidOperationException("Menu font atlas was not isolated from the game.");
						}
					}
				}
				ownedFont.atlasTextures = array;
				AccessTools.Field(typeof(TMP_FontAsset), "m_AtlasTexture")?.SetValue(ownedFont, null);
				if (array.Length == 0 || !Object.op_Implicit((Object)(object)array[0]) || (Object)(object)ownedFont.atlasTexture != (Object)(object)array[0])
				{
					throw new InvalidOperationException("Menu font is not using its private primary atlas.");
				}
				if (Object.op_Implicit((Object)(object)((TMP_Asset)font).material))
				{
					ownedFontMaterial = new Material(((TMP_Asset)font).material)
					{
						name = "QuietCrafting.MenuFont Material"
					};
					if (array.Length != 0 && Object.op_Implicit((Object)(object)array[0]))
					{
						ownedFontMaterial.mainTexture = (Texture)(object)array[0];
					}
					((TMP_Asset)ownedFont).material = ownedFontMaterial;
				}
				string text = new string((from code in Enumerable.Range(32, 95)
					select (char)code).ToArray());
				string text2 = default(string);
				ownedFont.TryAddCharacters(text, ref text2, false);
				if (!string.IsNullOrEmpty(text2))
				{
					Plugin.Warn("Menu font lacks printable characters: " + text2);
				}
				Plugin.Report($"Sound menu font: {array.Count((Texture2D atlas) => Object.op_Implicit((Object)(object)atlas))} private atlas texture(s); " + "dynamic glyph updates are isolated from the game font.");
				float num2 = 0f;
				float num3 = 0f;
				for (uint num4 = 33u; num4 <= 126; num4++)
				{
					if (ownedFont.characterLookupTable.TryGetValue(num4, out var value) && ((TMP_TextElement)value).glyph != null)
					{
						GlyphMetrics metrics = ((TMP_TextElement)value).glyph.metrics;
						num2 = Mathf.Max(num2, ((GlyphMetrics)(ref metrics)).horizontalBearingY);
						num3 = Mathf.Min(num3, ((GlyphMetrics)(ref metrics)).horizontalBearingY - ((GlyphMetrics)(ref metrics)).height);
					}
				}
				if (num2 > 0f)
				{
					FaceInfo faceInfo = ownedFont.faceInfo;
					((FaceInfo)(ref faceInfo)).ascentLine = num2 + 4f;
					((FaceInfo)(ref faceInfo)).descentLine = num3 - 4f;
					((FaceInfo)(ref faceInfo)).lineHeight = ((FaceInfo)(ref faceInfo)).ascentLine - ((FaceInfo)(ref faceInfo)).descentLine;
					ownedFont.faceInfo = faceInfo;
				}
				font = ownedFont;
			}
			if (Object.op_Implicit((Object)(object)font) && Object.op_Implicit((Object)(object)((TMP_Asset)font).material))
			{
				plainTextMaterial = new Material(((TMP_Asset)font).material)
				{
					name = "QuietCrafting.PlainText"
				};
				string[] array2 = new string[8] { "_FaceDilate", "_OutlineWidth", "_OutlineSoftness", "_WeightNormal", "_UnderlayDilate", "_UnderlayOffsetX", "_UnderlayOffsetY", "_UnderlaySoftness" };
				foreach (string text3 in array2)
				{
					if (plainTextMaterial.HasProperty(text3))
					{
						plainTextMaterial.SetFloat(text3, 0f);
					}
				}
				array2 = new string[3] { "_OutlineColor", "_UnderlayColor", "_GlowColor" };
				foreach (string text4 in array2)
				{
					if (plainTextMaterial.HasProperty(text4))
					{
						plainTextMaterial.SetColor(text4, Color.clear);
					}
				}
				array2 = new string[4] { "OUTLINE_ON", "UNDERLAY_ON", "UNDERLAY_INNER", "GLOW_ON" };
				foreach (string text5 in array2)
				{
					plainTextMaterial.DisableKeyword(text5);
				}
			}
			object arg = Object.op_Implicit((Object)(object)pressedButton);
			TMP_FontAsset? obj = font;
			Plugin.Report($"Sound menu theme: gold frame, upright tabs; native pressed artwork={arg}, font={((obj != null) ? ((Object)obj).name : null)}.");
			Sprite? Find(string name)
			{
				return ((IEnumerable<Sprite>)sprites).FirstOrDefault((Func<Sprite, bool>)((Sprite sprite) => Object.op_Implicit((Object)(object)sprite) && ((Object)sprite).name == name));
			}
		}

		internal RectTransform Rect(string name, Transform parent)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			return component;
		}

		internal RectTransform Place(string name, Transform parent, float x, float y, float width, float height)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Rect(name, parent);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			obj.pivot = val;
			Vector2 anchorMin = (obj.anchorMax = val);
			obj.anchorMin = anchorMin;
			obj.anchoredPosition = new Vector2(x, 0f - y);
			obj.sizeDelta = new Vector2(width, height);
			return obj;
		}

		internal Image Image(RectTransform rect, Sprite? sprite, Color fallback)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Image val = ((Component)rect).gameObject.AddComponent<Image>();
			val.sprite = sprite;
			int num;
			if (Object.op_Implicit((Object)(object)sprite))
			{
				Vector4 border = sprite.border;
				if (((Vector4)(ref border)).sqrMagnitude > 0f)
				{
					num = 1;
					goto IL_0035;
				}
			}
			num = 0;
			goto IL_0035;
			IL_0035:
			val.type = (Type)num;
			if (Object.op_Implicit((Object)(object)sprite))
			{
				val.pixelsPerUnitMultiplier = 100f / sprite.pixelsPerUnit;
			}
			((Graphic)val).color = (Object.op_Implicit((Object)(object)sprite) ? Color.white : fallback);
			return val;
		}

		internal TextMeshProUGUI Text(RectTransform rect, string text, float size, Color color, bool outlined = false)
		{
			//IL_004a: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = ((Component)rect).gameObject.AddComponent<TextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)font))
			{
				((TMP_Text)val).font = font;
			}
			if (!outlined && Object.op_Implicit((Object)(object)plainTextMaterial))
			{
				((TMP_Text)val).fontSharedMaterial = plainTextMaterial;
			}
			((TMP_Text)val).fontSize = size;
			((Graphic)val).color = color;
			((TMP_Text)val).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val).richText = false;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).enableWordWrapping = false;
			((TMP_Text)val).margin = Vector4.zero;
			((TMP_Text)val).enableAutoSizing = true;
			((TMP_Text)val).fontSizeMin = Mathf.Min(14f, size * 0.6f);
			((TMP_Text)val).fontSizeMax = size;
			((TMP_Text)val).overflowMode = (TextOverflowModes)3;
			if (outlined)
			{
				((TMP_Text)val).outlineColor = new Color32((byte)49, (byte)31, (byte)23, byte.MaxValue);
				((TMP_Text)val).outlineWidth = 0.14f;
			}
			((TMP_Text)val).text = text;
			return val;
		}

		internal Button Button(RectTransform rect, string caption, UnityAction action, float captionOffsetY = 0f, SoundGlyph? glyph = null)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			Image targetGraphic = Image(rect, RedButton, Red);
			SoundMenuButton soundMenuButton = ((Component)rect).gameObject.AddComponent<SoundMenuButton>();
			((Selectable)soundMenuButton).targetGraphic = (Graphic)(object)targetGraphic;
			ColorBlock colors = ((Selectable)soundMenuButton).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.92f, 0.72f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.78f, 0.67f, 0.5f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.55f, 0.55f, 0.55f, 0.65f);
			((Selectable)soundMenuButton).colors = colors;
			Navigation navigation = ((Selectable)soundMenuButton).navigation;
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)soundMenuButton).navigation = navigation;
			RectTransform val = Rect("Caption", (Transform)(object)rect);
			SoundLogWindow.Stretch(val);
			val.offsetMin = new Vector2(glyph.HasValue ? 40f : 8f, 4f);
			val.offsetMax = new Vector2(-8f, 0f);
			((TMP_Text)Text(val, caption, 38f, Cream, outlined: true)).alignment = (TextAlignmentOptions)4098;
			RectTransform val2 = null;
			if (glyph.HasValue)
			{
				float num = Mathf.Min(24f, Mathf.Min(rect.sizeDelta.x, rect.sizeDelta.y) - 8f);
				val2 = Place("Icon", (Transform)(object)rect, string.IsNullOrEmpty(caption) ? ((rect.sizeDelta.x - num) * 0.5f) : 12f, (rect.sizeDelta.y - num) * 0.5f - 1f, num, num);
				((Graphic)Image(val2, Art[glyph.Value], Cream)).raycastTarget = false;
			}
			if (string.IsNullOrEmpty(caption))
			{
				((Component)val).gameObject.SetActive(false);
			}
			soundMenuButton.BindCaption(val, captionOffsetY, val2);
			((UnityEvent)((Button)soundMenuButton).onClick).AddListener(action);
			SetToggle((Button)(object)soundMenuButton, enabled: false);
			return (Button)(object)soundMenuButton;
		}

		internal void SetToggle(Button button, bool enabled)
		{
			//IL_0075: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			((SoundMenuButton)(object)button).SetPressedFace(Object.op_Implicit((Object)(object)pressedButton), enabled);
			if (Object.op_Implicit((Object)(object)pressedButton))
			{
				Image component = ((Component)button).GetComponent<Image>();
				Sprite val = (Sprite)(enabled ? ((object)pressedButton) : ((object)RedButton));
				((Selectable)button).transition = (Transition)2;
				component.overrideSprite = null;
				component.sprite = val;
				((Graphic)component).color = (Color)(((Selectable)button).interactable ? Color.white : new Color(0.55f, 0.55f, 0.55f, 0.65f));
				SpriteState spriteState = default(SpriteState);
				((SpriteState)(ref spriteState)).highlightedSprite = (enabled ? pressedButton : (hoverButton ?? RedButton));
				((SpriteState)(ref spriteState)).pressedSprite = pressedButton;
				((SpriteState)(ref spriteState)).selectedSprite = val;
				((SpriteState)(ref spriteState)).disabledSprite = val;
				((Selectable)button).spriteState = spriteState;
				((SoundMenuButton)(object)button).RefreshState();
			}
		}

		internal void SetIcon(Button button, SoundGlyph glyph)
		{
			((Component)((Component)button).transform.Find("Icon")).GetComponent<Image>().sprite = Art[glyph];
		}

		internal Button PageTab(RectTransform rect, string caption, SoundGlyph glyph, UnityAction action)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			Image targetGraphic = Image(rect, Art.ActiveTab, PaperColor);
			Button obj = ((Component)rect).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic;
			((Selectable)obj).transition = (Transition)0;
			Navigation navigation = ((Selectable)obj).navigation;
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj).navigation = navigation;
			((Graphic)Image(Place("Tab icon", (Transform)(object)rect, (rect.sizeDelta.x - 28f) * 0.5f, 8f, 28f, 28f), Art[glyph], Cream)).raycastTarget = false;
			((TMP_Text)Text(Place("Caption", (Transform)(object)rect, 8f, 34f, rect.sizeDelta.x - 16f, 38f), caption, 36f, Cream, outlined: true)).alignment = (TextAlignmentOptions)4098;
			((UnityEvent)obj.onClick).AddListener(action);
			return obj;
		}

		internal void SelectTab(Button button, bool selected)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)button).transform;
			val.anchoredPosition = new Vector2(val.anchoredPosition.x, selected ? 0f : (-8f));
			val.sizeDelta = new Vector2(val.sizeDelta.x, selected ? 86f : 78f);
			((Component)button).GetComponent<Image>().sprite = (selected ? Art.ActiveTab : Art.InactiveTab);
		}

		internal TMP_InputField Search(RectTransform rect)
		{
			//IL_000d: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			Image targetGraphic = Image(rect, Art.Field, PaperColor);
			Image obj = Image(Place("Search icon", (Transform)(object)rect, 14f, 14f, 24f, 24f), Art[SoundGlyph.Search], Ink);
			((Graphic)obj).raycastTarget = false;
			((Graphic)obj).color = Ink;
			RectTransform val = Rect("Text area", (Transform)(object)rect);
			SoundLogWindow.Stretch(val);
			val.offsetMin = new Vector2(48f, 4f);
			val.offsetMax = new Vector2(-14f, -4f);
			((Component)val).gameObject.AddComponent<RectMask2D>();
			RectTransform rect2 = Rect("Value", (Transform)(object)val);
			SoundLogWindow.Stretch(rect2);
			TextMeshProUGUI textComponent = Text(rect2, "", 38f, Ink);
			RectTransform rect3 = Rect("Placeholder", (Transform)(object)val);
			SoundLogWindow.Stretch(rect3);
			TextMeshProUGUI val2 = Text(rect3, "Search sound names...", 38f, Ink);
			((TMP_Text)val2).alpha = 0.75f;
			TMP_InputField obj2 = ((Component)rect).gameObject.AddComponent<TMP_InputField>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)targetGraphic;
			obj2.textViewport = val;
			obj2.textComponent = (TMP_Text)(object)textComponent;
			obj2.placeholder = (Graphic)(object)val2;
			obj2.lineType = (LineType)0;
			obj2.characterLimit = 120;
			obj2.pointSize = 38f;
			obj2.customCaretColor = true;
			obj2.caretColor = Ink;
			return obj2;
		}

		internal static void SetLabel(Button button, string text)
		{
			((TMP_Text)((Component)button).GetComponentInChildren<TextMeshProUGUI>(true)).text = text;
		}

		public void Dispose()
		{
			Art.Dispose();
			if (Object.op_Implicit((Object)(object)plainTextMaterial))
			{
				Object.Destroy((Object)(object)plainTextMaterial);
			}
			if (Object.op_Implicit((Object)(object)ownedFontMaterial))
			{
				Object.Destroy((Object)(object)ownedFontMaterial);
			}
			if (!Object.op_Implicit((Object)(object)ownedFont))
			{
				return;
			}
			foreach (Texture2D item in ownedFont.atlasTextures.Distinct())
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Object.Destroy((Object)(object)item);
				}
			}
			Object.Destroy((Object)(object)ownedFont);
		}
	}
	internal static class PlaybackVolumes
	{
		private sealed class TrackedSource
		{
			internal readonly AudioSource Source;

			internal readonly string ClipName;

			internal float RequestedVolume;

			internal TrackedSource(AudioSource source, string name, float volume)
			{
				Source = source;
				ClipName = name;
				RequestedVolume = volume;
			}
		}

		private static readonly Dictionary<int, TrackedSource> sources = new Dictionary<int, TrackedSource>();

		private static int writes;

		internal static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo setter = AccessTools.PropertySetter(typeof(AudioSource), "volume");
			MethodInfo replacement = AccessTools.Method(typeof(PlaybackVolumes), "SetVolume", (Type[])null, (Type[])null);
			int replaced = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, setter))
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = replacement;
					replaced++;
				}
				yield return instruction;
			}
			if (replaced == 0)
			{
				throw new InvalidOperationException("No AudioSource volume setter was found; sound-menu volume hook cannot be installed.");
			}
		}

		private static void SetVolume(AudioSource source, float requestedVolume)
		{
			if (Object.op_Implicit((Object)(object)source))
			{
				int instanceID = ((Object)source).GetInstanceID();
				if (!sources.TryGetValue(instanceID, out TrackedSource value) || !Object.op_Implicit((Object)(object)value.Source) || (Object)(object)value.Source != (Object)(object)source)
				{
					string name = (Object.op_Implicit((Object)(object)source.clip) ? ((Object)source.clip).name : ((Object)((Component)source).gameObject).name);
					value = new TrackedSource(source, name, requestedVolume);
					sources[instanceID] = value;
				}
				value.RequestedVolume = requestedVolume;
				source.volume = (Plugin.IsEffectivelyMuted(value.ClipName) ? 0f : requestedVolume);
				if (++writes % 128 == 0)
				{
					Prune();
				}
			}
		}

		internal static void Refresh()
		{
			foreach (TrackedSource value in sources.Values)
			{
				if (Object.op_Implicit((Object)(object)value.Source))
				{
					value.Source.volume = (Plugin.IsEffectivelyMuted(value.ClipName) ? 0f : value.RequestedVolume);
				}
			}
			Prune();
		}

		private static void Prune()
		{
			int[] array = (from pair in sources
				where !Object.op_Implicit((Object)(object)pair.Value.Source)
				select pair.Key).ToArray();
			foreach (int key in array)
			{
				sources.Remove(key);
			}
		}
	}
	internal sealed class PlayerInputHold
	{
		private const string Key = "QuietCrafting.SoundMenu";

		private Object? heldPlayer;

		private MethodInfo? release;

		internal void Acquire()
		{
			if (Object.op_Implicit(heldPlayer))
			{
				return;
			}
			try
			{
				Type type = AccessTools.TypeByName("Wish.Player");
				object? obj = type?.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
				Object val = (Object)((obj is Object) ? obj : null);
				MethodInfo methodInfo = type?.GetMethod("AddPauseObject", new Type[1] { typeof(string) });
				MethodInfo methodInfo2 = type?.GetMethod("RemovePauseObject", new Type[1] { typeof(string) });
				if (Object.op_Implicit(val) && !(methodInfo == null) && !(methodInfo2 == null))
				{
					methodInfo.Invoke(val, new object[1] { "QuietCrafting.SoundMenu" });
					heldPlayer = val;
					release = methodInfo2;
				}
			}
			catch (Exception arg)
			{
				Plugin.Warn($"Could not hold sound menu input: {arg}");
			}
		}

		internal void Release()
		{
			try
			{
				if (Object.op_Implicit(heldPlayer))
				{
					release?.Invoke(heldPlayer, new object[1] { "QuietCrafting.SoundMenu" });
				}
			}
			catch (Exception arg)
			{
				Plugin.Warn($"Could not release sound menu input: {arg}");
			}
			finally
			{
				heldPlayer = null;
				release = null;
			}
		}
	}
	[BepInPlugin("local.sunhaven.quietcrafting", "Quiet Crafting", "1.0.0")]
	[BepInProcess("Sun Haven.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginId = "local.sunhaven.quietcrafting";

		public const string PluginName = "Quiet Crafting";

		public const string PluginVersion = "1.0.0";

		private static ConfigEntry<bool> modEnabled = null;

		private static ConfigEntry<bool> logSounds = null;

		private static ManualLogSource log = null;

		private static volatile SoundCatalog catalog = new SoundCatalog("WoodcuttingTable2; ElvenCraftingTable1", string.Empty);

		private static ConfigEntry<string> mutedClips = null;

		private static ConfigEntry<string> savedClips = null;

		private static ConfigFile configFile = null;

		private static bool saving;

		internal static readonly RecentSounds History = new RecentSounds();

		private static readonly HashSet<string> loggedSounds = new HashSet<string>(StringComparer.Ordinal);

		private static readonly object logLock = new object();

		internal static int SettingsGeneration { get; private set; }

		internal static string[] SavedNames => catalog.SavedNames;

		internal static bool MutingEnabled
		{
			get
			{
				return modEnabled.Value;
			}
			set
			{
				modEnabled.Value = value;
			}
		}

		private void Awake()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Expected O, but got Unknown
			log = ((BaseUnityPlugin)this).Logger;
			configFile = ((BaseUnityPlugin)this).Config;
			modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable selective sound muting.");
			mutedClips = ((BaseUnityPlugin)this).Config.Bind<string>("Sounds", "MutedClips", "WoodcuttingTable2; ElvenCraftingTable1", "Exact AudioClip names to silence, separated by semicolons. Case insensitive. Example: WoodcuttingTable2; ElvenCraftingTable1. Empty means mute nothing. Use /sounds in chat to discover names and toggle them. No wildcards or file extensions.");
			logSounds = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "LogSounds", false, "Log each sound name once per session to BepInEx/LogOutput.log. Reproduce the unwanted sound, then copy its Clip name into MutedClips. Only sounds sent through the patched game audio methods are listed.");
			ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("General", "DefaultsRevision", 0, new ConfigDescription("Internal marker for upgrading an unchanged older preset. Custom blacklists are preserved.", (AcceptableValueBase)null, new object[1]
			{
				new
				{
					Browsable = false
				}
			}));
			string text = DefaultSettings.UpgradePreset(mutedClips.Value, val.Value);
			if (text != mutedClips.Value)
			{
				mutedClips.Value = text;
				log.LogInfo((object)"Updated the original 0.1.0 preset to WoodcuttingTable2; ElvenCraftingTable1.");
			}
			if (val.Value < 1)
			{
				val.Value = 1;
			}
			savedClips = ((BaseUnityPlugin)this).Config.Bind<string>("Sounds", "SavedClips", string.Empty, "Sounds remembered in the sound menu's Saved sounds tab, including previously muted sounds. Use Remove in that tab to unmute and forget a sound. Semicolon separated.");
			catalog = new SoundCatalog(mutedClips.Value, savedClips.Value);
			savedClips.Value = catalog.SavedText;
			mutedClips.SettingChanged += delegate
			{
				ReloadCatalog();
			};
			savedClips.SettingChanged += delegate
			{
				ReloadCatalog();
			};
			modEnabled.SettingChanged += delegate
			{
				SettingsGeneration++;
				PlaybackVolumes.Refresh();
			};
			logSounds.SettingChanged += delegate
			{
				lock (logLock)
				{
					loggedSounds.Clear();
				}
			};
			Type type = AccessTools.TypeByName("Wish.AudioManager");
			if (type == null)
			{
				log.LogError((object)"Wish.AudioManager was not found. No audio was changed.");
				return;
			}
			Harmony val2 = new Harmony("local.sunhaven.quietcrafting");
			HarmonyMethod val3 = new HarmonyMethod(typeof(Plugin), "FilterSound", (Type[])null);
			HarmonyMethod val4 = new HarmonyMethod(typeof(PlaybackVolumes), "Transpile", (Type[])null);
			int num = 0;
			string[] array = new string[3] { "PlayAudioInternal", "PlayAudioImmediate", "PlayAudioDontDestroy" };
			foreach (string name in array)
			{
				MethodInfo[] array2 = (from methodInfo in AccessTools.GetDeclaredMethods(type)
					where methodInfo.Name == name && HasAudioParameters(methodInfo)
					select methodInfo).ToArray();
				if (array2.Length != 1)
				{
					log.LogWarning((object)$"Expected one compatible AudioManager.{name}; found {array2.Length}. Skipped.");
					continue;
				}
				try
				{
					val2.Patch((MethodBase)array2[0], val3, (HarmonyMethod)null, val4, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception arg)
				{
					log.LogError((object)$"Could not patch AudioManager.{name}: {arg}");
				}
			}
			MethodInfo[] array3 = (from methodInfo in (from type2 in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)
					where type2.GetField("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.FieldType == typeof(AudioClip) && type2.GetField("volume", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.FieldType == typeof(float)
					select type2).SelectMany((Func<Type, IEnumerable<MethodInfo>>)AccessTools.GetDeclaredMethods)
				where methodInfo.Name.StartsWith("<PlayOneShot>b__", StringComparison.Ordinal) && methodInfo.ReturnType == typeof(void) && methodInfo.GetParameters().Length == 0
				select methodInfo).ToArray();
			if (array3.Length == 1)
			{
				try
				{
					val2.Patch((MethodBase)array3[0], new HarmonyMethod(typeof(Plugin), "FilterQueuedSound", (Type[])null), (HarmonyMethod)null, val4, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception arg2)
				{
					log.LogError((object)$"Could not patch the PlayOneShot callback: {arg2}");
				}
			}
			else
			{
				log.LogWarning((object)$"Expected one compatible PlayOneShot callback; found {array3.Length}. Crafting audio may remain audible.");
			}
			if (num == 0)
			{
				log.LogError((object)"No compatible audio methods could be patched. No audio was changed.");
			}
			else
			{
				log.LogInfo((object)$"Ready: patched {num}/4 audio methods; {catalog.MutedCount} sound(s) blacklisted. Config: {((BaseUnityPlugin)this).Config.ConfigFilePath}");
			}
			try
			{
				MethodInfo method = type.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					val2.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, val4, (HarmonyMethod)null, (HarmonyMethod)null);
					log.LogInfo((object)$"Live volume control ready: {num + 1}/5 managed paths.");
				}
				else
				{
					log.LogWarning((object)"AudioManager.Update was not found; looping sounds may override mute state.");
				}
			}
			catch (Exception arg3)
			{
				log.LogError((object)$"Could not install looping-volume hook: {arg3}");
			}
			try
			{
				if (ChatCommand.Install(val2))
				{
					log.LogInfo((object)"Sound menu ready: /sounds (live mute controls and saved sounds).");
				}
			}
			catch (Exception arg4)
			{
				log.LogError((object)$"Could not install /sounds: {arg4}");
			}
		}

		private static bool HasAudioParameters(MethodInfo method)
		{
			ParameterInfo[] parameters = method.GetParameters();
			if (parameters.Length != 0 && parameters[0].ParameterType == typeof(AudioClip))
			{
				return parameters.Any((ParameterInfo parameter) => parameter.Name == "volume" && parameter.ParameterType == typeof(float));
			}
			return false;
		}

		private static void FilterSound(AudioClip __0, MethodBase __originalMethod)
		{
			ApplyFilter(__0, __originalMethod.Name);
		}

		private static void FilterQueuedSound(AudioClip ___clip)
		{
			ApplyFilter(___clip, "PlayOneShot");
		}

		private static void ApplyFilter(AudioClip clip, string method)
		{
			if (!Object.op_Implicit((Object)(object)clip))
			{
				return;
			}
			string name = ((Object)clip).name;
			bool flag = IsEffectivelyMuted(name);
			History.Add(name, method, flag);
			if (logSounds.Value)
			{
				bool flag2;
				lock (logLock)
				{
					flag2 = loggedSounds.Add(name);
				}
				if (flag2)
				{
					log.LogInfo((object)$"[Sound] Clip=\"{name}\" Muted={flag} Via={method}");
				}
			}
		}

		internal static bool IsEffectivelyMuted(string name)
		{
			if (modEnabled.Value)
			{
				return catalog.IsMuted(name);
			}
			return false;
		}

		internal static bool IsSelectedMuted(string name)
		{
			return catalog.IsMuted(name);
		}

		internal static void SetMuted(string name, bool value)
		{
			SaveCatalog(catalog.WithMute(name, value));
		}

		internal static void RemoveSaved(string name)
		{
			SaveCatalog(catalog.WithoutSaved(name));
		}

		private static void ReloadCatalog()
		{
			if (!saving)
			{
				catalog = new SoundCatalog(mutedClips.Value, savedClips.Value);
				saving = true;
				try
				{
					savedClips.Value = catalog.SavedText;
				}
				finally
				{
					saving = false;
				}
				SettingsGeneration++;
				PlaybackVolumes.Refresh();
			}
		}

		private static void SaveCatalog(SoundCatalog next)
		{
			SoundCatalog soundCatalog = catalog;
			bool saveOnConfigSet = configFile.SaveOnConfigSet;
			saving = true;
			try
			{
				configFile.SaveOnConfigSet = false;
				mutedClips.Value = next.MutedText;
				savedClips.Value = next.SavedText;
				configFile.Save();
				catalog = next;
			}
			catch
			{
				mutedClips.Value = soundCatalog.MutedText;
				savedClips.Value = soundCatalog.SavedText;
				throw;
			}
			finally
			{
				configFile.SaveOnConfigSet = saveOnConfigSet;
				saving = false;
			}
			SettingsGeneration++;
			PlaybackVolumes.Refresh();
		}

		internal static void Warn(string message)
		{
			log.LogWarning((object)message);
		}

		internal static void Report(string message)
		{
			log.LogInfo((object)message);
		}
	}
	internal sealed class SoundEntry
	{
		internal DateTime Timestamp { get; }

		internal string Name { get; }

		internal string Method { get; }

		internal bool Muted { get; }

		internal SoundEntry(DateTime timestamp, string name, string method, bool muted)
		{
			Timestamp = timestamp;
			Name = name;
			Method = method;
			Muted = muted;
		}

		public override string ToString()
		{
			return $"{Timestamp:HH:mm:ss.fff} | Clip=\"{Name}\" Muted={Muted} Via={Method}";
		}
	}
	internal sealed class RecentSounds
	{
		internal const int Capacity = 200;

		private readonly Queue<SoundEntry> entries = new Queue<SoundEntry>(200);

		private readonly object gate = new object();

		internal void Add(string name, string method, bool muted)
		{
			lock (gate)
			{
				if (entries.Count == 200)
				{
					entries.Dequeue();
				}
				entries.Enqueue(new SoundEntry(DateTime.Now, name, method, muted));
			}
		}

		internal SoundEntry[] Snapshot()
		{
			lock (gate)
			{
				SoundEntry[] array = entries.ToArray();
				Array.Reverse((Array)array);
				return array;
			}
		}

		internal void Clear()
		{
			lock (gate)
			{
				entries.Clear();
			}
		}
	}
	internal sealed class SoundCatalog
	{
		private readonly HashSet<string> muted;

		private readonly HashSet<string> saved;

		internal int MutedCount => muted.Count;

		internal string[] SavedNames => Sorted(saved);

		internal string MutedText => string.Join("; ", Sorted(muted));

		internal string SavedText => string.Join("; ", Sorted(saved));

		internal SoundCatalog(string mutedText, string savedText)
		{
			muted = Parse(mutedText);
			saved = Parse(savedText);
			saved.UnionWith(muted);
		}

		private SoundCatalog(HashSet<string> muted, HashSet<string> saved)
		{
			this.muted = muted;
			this.saved = saved;
		}

		internal bool IsMuted(string name)
		{
			return muted.Contains(name);
		}

		internal SoundCatalog WithMute(string name, bool value)
		{
			HashSet<string> hashSet = new HashSet<string>(muted, StringComparer.OrdinalIgnoreCase);
			HashSet<string> hashSet2 = new HashSet<string>(saved, StringComparer.OrdinalIgnoreCase);
			name = name.Trim();
			if (name.Length != 0)
			{
				if (value)
				{
					hashSet.Add(name);
					hashSet2.Add(name);
				}
				else
				{
					hashSet.Remove(name);
				}
			}
			return new SoundCatalog(hashSet, hashSet2);
		}

		internal SoundCatalog WithoutSaved(string name)
		{
			HashSet<string> hashSet = new HashSet<string>(muted, StringComparer.OrdinalIgnoreCase);
			HashSet<string> hashSet2 = new HashSet<string>(saved, StringComparer.OrdinalIgnoreCase);
			hashSet.Remove(name);
			hashSet2.Remove(name);
			return new SoundCatalog(hashSet, hashSet2);
		}

		private static HashSet<string> Parse(string text)
		{
			return new HashSet<string>(from name in text.Split(new char[1] { ';' })
				select name.Trim() into name
				where name.Length > 0
				select name, StringComparer.OrdinalIgnoreCase);
		}

		private static string[] Sorted(IEnumerable<string> names)
		{
			return names.OrderBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase).ToArray();
		}
	}
	internal static class SoundLogCommandText
	{
		internal static bool Matches(string? text)
		{
			return string.Equals(text?.Trim(), "/sounds", StringComparison.OrdinalIgnoreCase);
		}
	}
	public sealed class SoundLogWindow : MonoBehaviour
	{
		private sealed class MenuItem
		{
			internal readonly string Name;

			internal readonly string Detail;

			internal MenuItem(string name, string detail)
			{
				Name = name;
				Detail = detail;
			}
		}

		private sealed class MenuRow
		{
			private readonly SoundLogWindow owner;

			private readonly RectTransform rect;

			private readonly Image background;

			private readonly Image separator;

			private readonly TextMeshProUGUI nameLabel;

			private readonly TextMeshProUGUI detail;

			private readonly Button mute;

			private readonly Button remove;

			private string name = string.Empty;

			private string? muteTarget;

			private string? removeTarget;

			internal MenuRow(SoundLogWindow owner, Transform parent)
			{
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Expected O, but got Unknown
				//IL_0241: Unknown result type (might be due to invalid IL or missing references)
				//IL_0259: Expected O, but got Unknown
				MenuRow menuRow = this;
				this.owner = owner;
				rect = owner.Place("Sound", parent, 0f, 0f, 1004f, 54f);
				background = owner.theme.Image(rect, null, Color.clear);
				((Graphic)background).raycastTarget = false;
				nameLabel = owner.theme.Text(owner.Place("Name", (Transform)(object)rect, 144f, 0f, 680f, 54f), "", 44f, NativeSoundTheme.Cream, outlined: true);
				((TMP_Text)nameLabel).fontSizeMin = 32f;
				detail = owner.theme.Text(owner.Place("Timestamp", (Transform)(object)rect, 20f, 0f, 100f, 54f), "", 32f, NativeSoundTheme.Ink);
				separator = owner.theme.Image(owner.Place("Time separator", (Transform)(object)rect, 126f, 16f, 1f, 22f), null, new Color(0.4f, 0.27f, 0.16f, 0.5f));
				((Graphic)separator).raycastTarget = false;
				mute = owner.theme.Button(owner.Place("Mute", (Transform)(object)rect, 846f, 5f, 144f, 44f), "Mute", (UnityAction)delegate
				{
					string text = menuRow.muteTarget ?? menuRow.name;
					menuRow.muteTarget = null;
					owner.ChangeMute(text);
				});
				remove = owner.theme.Button(owner.Place("Remove", (Transform)(object)rect, 836f, 5f, 154f, 44f), "Remove", (UnityAction)delegate
				{
					string text = menuRow.removeTarget ?? menuRow.name;
					menuRow.removeTarget = null;
					owner.Forget(text);
				});
				((Component)mute).gameObject.AddComponent<SoundButtonPress>().Capture = delegate
				{
					menuRow.muteTarget = menuRow.name;
				};
				((Component)remove).gameObject.AddComponent<SoundButtonPress>().Capture = delegate
				{
					menuRow.removeTarget = menuRow.name;
				};
			}

			internal void Bind(MenuItem? item, int index, bool saved)
			{
				//IL_0038: 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_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: 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_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_0156: Unknown result type (might be due to invalid IL or missing references)
				((Component)rect).gameObject.SetActive(item != null);
				if (item != null)
				{
					name = item.Name;
					rect.anchoredPosition = new Vector2(0f, (float)(-index) * 54f);
					((Graphic)background).color = (Color)((index % 2 == 0) ? new Color(0.32f, 0.13f, 0.04f, 0.09f) : Color.clear);
					((TMP_Text)nameLabel).text = item.Name;
					((TMP_Text)detail).text = item.Detail;
					((Component)detail).gameObject.SetActive(!saved);
					((Component)separator).gameObject.SetActive(!saved);
					((TMP_Text)nameLabel).rectTransform.anchoredPosition = new Vector2(saved ? 20f : 144f, 0f);
					((TMP_Text)nameLabel).rectTransform.sizeDelta = new Vector2(saved ? 644f : 680f, 54f);
					((RectTransform)((Component)mute).transform).anchoredPosition = new Vector2(saved ? 680f : 846f, -5f);
					((RectTransform)((Component)mute).transform).sizeDelta = new Vector2(144f, 44f);
					bool flag = Plugin.IsSelectedMuted(name);
					NativeSoundTheme.SetLabel(mute, flag ? "Unmute" : "Mute");
					owner.theme.SetToggle(mute, flag);
					((Component)remove).gameObject.SetActive(saved);
				}
			}
		}

		private const float RowHeight = 54f;

		private static SoundLogWindow? instance;

		private readonly PlayerInputHold inputHold = new PlayerInputHold();

		private readonly List<MenuRow> rowPool = new List<MenuRow>();

		private SoundEntry[] snapshot = Array.Empty<SoundEntry>();

		private MenuItem[] items = Array.Empty<MenuItem>();

		private GameObject root;

		private NativeSoundTheme theme;

		private RectTransform content;

		private RectTransform viewport;

		private ScrollRect scroll;

		private TMP_InputField search;

		private TextMeshProUGUI pageTitle;

		private TextMeshProUGUI countLabel;

		private TextMeshProUGUI hint;

		private TextMeshProUGUI helper;

		private TextMeshProUGUI status;

		private TextMeshProUGUI empty;

		private Image enabledLamp;

		private Button logTab;

		private Button savedTab;

		private Button pauseButton;

		private Button clearButton;

		private Button enableButton;

		private bool saved;

		private bool frozen;

		private bool rebuilding;

		private float nextRefresh;

		private int settingsGeneration = -1;

		private int firstRow = -1;

		internal static void Show()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)instance))
			{
				GameObject val = new GameObject("QuietCrafting.SoundMenu");
				Object.DontDestroyOnLoad((Object)(object)val);
				instance = val.AddComponent<SoundLogWindow>();
				try
				{
					instance.Build();
				}
				catch
				{
					Object.Destroy((Object)(object)val);
					instance = null;
					throw;
				}
			}
			instance.root.SetActive(true);
			instance.snapshot = Plugin.History.Snapshot();
			instance.inputHold.Acquire();
			instance.RefreshItems();
			((MonoBehaviour)instance).StartCoroutine(instance.CheckTextMeshes());
		}

		private IEnumerator CheckTextMeshes()
		{
			yield return null;
			if (!Object.op_Implicit((Object)(object)root) || !root.activeInHierarchy)
			{
				yield break;
			}
			Canvas.ForceUpdateCanvases();
			int num = 0;
			int num2 = 0;
			TextMeshProUGUI[] componentsInChildren = root.GetComponentsInChildren<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in componentsInChildren)
			{
				if (((Behaviour)val).isActiveAndEnabled && ((TMP_Text)val).text.Any((char character) => !char.IsWhiteSpace(character) && !char.IsControl(character) && char.GetUnicodeCategory(character) != UnicodeCategory.Format))
				{
					num++;
					((TMP_Text)val).ForceMeshUpdate(false, false);
					if (!((TMP_Text)val).textInfo.characterInfo.Take(((TMP_Text)val).textInfo.characterCount).Any((TMP_CharacterInfo character) => character.isVisible))
					{
						num2++;
						string[] obj = new string[6]
						{
							"Empty sound menu text mesh: ",
							((Object)((Component)val).gameObject).name,
							", text=",
							((TMP_Text)val).text,
							", ",
							null
						};
						Rect rect = ((TMP_Text)val).rectTransform.rect;
						object arg = ((Rect)(ref rect)).size;
						TMP_FontAsset font = ((TMP_Text)val).font;
						obj[5] = $"box={arg}, font={((font != null) ? ((Object)font).name : null)}, size={((TMP_Text)val).fontSize}.";
						Plugin.Warn(string.Concat(obj));
					}
				}
			}
			Plugin.Report($"Sound menu text: {num} nonempty labels checked; {num2} empty meshes.");
		}

		private void Build()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Expected O, but got Unknown
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Expected O, but got Unknown
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Expected O, but got Unknown
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Expected O, but got Unknown
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_073e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0754: Unknown result type (might be due to invalid IL or missing references)
			//IL_078c: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0813: Expected O, but got Unknown
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_085c: Expected O, but got Unknown
			//IL_0893: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0919: Unknown result type (might be due to invalid IL or missing references)
			//IL_092e: Expected O, but got Unknown
			//IL_096a: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa0: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			theme = new NativeSoundTheme();
			root = new GameObject("Sounds", new Type[4]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			root.transform.SetParent(((Component)this).transform, false);
			root.SetActive(false);
			Canvas component = root.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 32000;
			component.pixelPerfect = true;
			CanvasScaler component2 = root.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1280f, 900f);
			component2.screenMatchMode = (ScreenMatchMode)1;
			if (!Object.op_Implicit((Object)(object)EventSystem.current))
			{
				new GameObject("MenuEventSystem", new Type[2]
				{
					typeof(EventSystem),
					typeof(StandaloneInputModule)
				}).transform.SetParent(root.transform, false);
			}
			RectTransform rect = theme.Rect("Backdrop", root.transform);
			Stretch(rect);
			theme.Image(rect, null, new Color(0.04f, 0.025f, 0.02f, 0.63f));
			RectTransform val = theme.Rect("Sound menu", root.transform);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			val.pivot = val2;
			Vector2 anchorMin = (val.anchorMax = val2);
			val.anchorMin = anchorMin;
			val.sizeDelta = new Vector2(1120f, 734f);
			logTab = theme.PageTab(Place("Log tab", (Transform)(object)val, 188f, 0f, 160f, 86f), "Sound log", SoundGlyph.Wave, (UnityAction)delegate
			{
				SelectTab(value: false);
			});
			savedTab = theme.PageTab(Place("Saved tab", (Transform)(object)val, 358f, 0f, 220f, 86f), "Saved sounds", SoundGlyph.Bookmark, (UnityAction)delegate
			{
				SelectTab(value: true);
			});
			theme.Image(Place("Gold window frame", (Transform)(object)val, 0f, 80f, 1120f, 654f), theme.Frame, NativeSoundTheme.Red);
			((Graphic)theme.Image(Place("Header", (Transform)(object)val, 8f, 88f, 1104f, 50f), null, NativeSoundTheme.Red)).raycastTarget = false;
			((Graphic)theme.Image(Place("Header shadow", (Transform)(object)val, 8f, 138f, 1104f, 10f), null, NativeSoundTheme.Brown)).raycastTarget = false;
			((TMP_Text)theme.Text(Place("Title", (Transform)(object)val, 280f, 82f, 560f, 60f), "Sounds", 60f, NativeSoundTheme.Gold, outlined: true)).alignment = (TextAlignmentOptions)4098;
			RectTransform val4 = Place("Tab page", (Transform)(object)val, 24f, 154f, 1072f, 558f);
			theme.Image(val4, theme.Paper, NativeSoundTheme.PaperColor);
			pageTitle = theme.Text(Place("Page heading", (Transform)(object)val4, 20f, 8f, 430f, 40f), "Sound log", 44f, NativeSoundTheme.Cream, outlined: true);
			countLabel = theme.Text(Place("Count", (Transform)(object)val4, 500f, 8f, 552f, 40f), "", 32f, NativeSoundTheme.Cream, outlined: true);
			((TMP_Text)countLabel).alignment = (TextAlignmentOptions)4100;
			search = theme.Search(Place("Search", (Transform)(object)val4, 20f, 56f, 492f, 52f));
			((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				content.anchoredPosition = Vector2.zero;
				RefreshItems();
			});
			pauseButton = theme.Button(Place("Pause log", (Transform)(object)val4, 524f, 56f, 174f, 52f), "Pause log", (UnityAction)delegate
			{
				frozen = !frozen;
				if (!frozen)
				{
					snapshot = Plugin.History.Snapshot();
				}
				RefreshItems();
			}, 0f, SoundGlyph.Pause);
			clearButton = theme.Button(Place("Clear log", (Transform)(object)val4, 710f, 56f, 142f, 52f), "Clear", (UnityAction)delegate
			{
				Plugin.History.Clear();
				snapshot = Array.Empty<SoundEntry>();
				RefreshItems();
			}, 0f, SoundGlyph.Trash);
			theme.Button(Place("Copy", (Transform)(object)val4, 864f, 56f, 188f, 52f), "Copy list", (UnityAction)delegate
			{
				GUIUtility.systemCopyBuffer = string.Join(Environment.NewLine, items.Select((MenuItem item) => $"{item.Name} | Muted={Plugin.IsSelectedMuted(item.Name)} | {item.Detail}"));
				((TMP_Text)status).text = "Copied the displayed list, including full clip names.";
			}, 0f, SoundGlyph.Copy);
			RectTransform val5 = Place("Sound list", (Transform)(object)val4, 20f, 122f, 1032f, 328f);
			theme.Image(val5, theme.Art.List, NativeSoundTheme.PaperColor);
			scroll = ((Component)val5).gameObject.AddComponent<ScrollRect>();
			viewport = theme.Rect("Viewport", (Transform)(object)val5);
			Stretch(viewport);
			viewport.offsetMin = new Vector2(2f, 2f);
			viewport.offsetMax = new Vector2(-26f, -2f);
			((Component)viewport).gameObject.AddComponent<RectMask2D>();
			content = theme.Rect("Content", (Transform)(object)viewport);
			content.anchorMin = new Vector2(0f, 1f);
			content.anchorMax = new Vector2(1f, 1f);
			content.pivot = new Vector2(0.5f, 1f);
			content.sizeDelta = Vector2.zero;
			scroll.viewport = viewport;
			scroll.content = content;
			scroll.horizontal = false;
			scroll.movementType = (MovementType)2;
			scroll.scrollSensitivity = 32f;
			((UnityEvent<Vector2>)(object)scroll.onValueChanged).AddListener((UnityAction<Vector2>)delegate
			{
				RenderRows();
			});
			RectTransform val6 = Place("Scrollbar", (Transform)(object)val5, 1010f, 24f, 22f, 280f);
			theme.Image(val6, theme.ScrollTrack, NativeSoundTheme.Brown);
			Scrollbar val7 = ((Component)val6).gameObject.AddComponent<Scrollbar>();
			RectTransform val8 = theme.Rect("Sliding area", (Transform)(object)val6);
			Stretch(val8);
			val8.offsetMin = new Vector2(2f, 2f);
			val8.offsetMax = new Vector2(-2f, -2f);
			RectTransform val9 = theme.Rect("Handle", (Transform)(object)val8);
			Stretch(val9);
			Image targetGraphic = theme.Image(val9, theme.ScrollHandle, NativeSoundTheme.Gold);
			val7.handleRect = val9;
			((Selectable)val7).targetGraphic = (Graphic)(object)targetGraphic;
			val7.direction = (Direction)2;
			scroll.verticalScrollbar = val7;
			scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0;
			theme.Button(Place("Scroll up", (Transform)(object)val5, 1010f, 0f, 22f, 22f), "", (UnityAction)delegate
			{
				ScrollPage(1f);
			}, 0f, SoundGlyph.Up);
			theme.Button(Place("Scroll down", (Transform)(object)val5, 1010f, 306f, 22f, 22f), "", (UnityAction)delegate
			{
				ScrollPage(-1f);
			}, 0f, SoundGlyph.Down);
			empty = theme.Text(Place("Empty", (Transform)(object)viewport, 20f, 20f, 950f, 80f), "", 28f, NativeSoundTheme.Ink);
			((TMP_Text)empty).enableWordWrapping = true;
			((Graphic)theme.Image(Place("Footer divider", (Transform)(object)val4, 20f, 462f, 1032f, 2f), null, NativeSoundTheme.Brown)).raycastTarget = false;
			enableButton = theme.Button(Place("Global enable", (Transform)(object)val4, 28f, 476f, 220f, 48f), "Global Enable", (UnityAction)delegate
			{
				Plugin.MutingEnabled = !Plugin.MutingEnabled;
				RefreshItems();
			}, -1f, SoundGlyph.Check);
			enabledLamp = theme.Image(Place("Enabled indicator", (Transform)(object)val4, 276f, 490f, 20f, 20f), theme.Art.LampOn, NativeSoundTheme.Gold);
			((Graphic)enabledLamp).raycastTarget = false;
			hint = theme.Text(Place("Global state", (Transform)(object)val4, 320f, 470f, 720f, 32f), "", 32f, NativeSoundTheme.Ink);
			helper = theme.Text(Place("Global help", (Transform)(object)val4, 320f, 502f, 720f, 28f), "", 28f, NativeSoundTheme.Ink);
			status = theme.Text(Place("Status", (Transform)(object)val4, 20f, 532f, 1032f, 24f), "Changes save automatically. Esc closes.", 24f, NativeSoundTheme.Ink);
			((TMP_Text)status).alignment = (TextAlignmentOptions)4098;
			theme.Button(Place("Close", (Transform)(object)val, 1088f, 60f, 50f, 50f), "", new UnityAction(Close), 0f, SoundGlyph.Close);
			for (int num = 0; num < 9; num++)
			{
				rowPool.Add(new MenuRow(this, (Transform)(object)content));
			}
		}

		private void ScrollPage(float direction)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = content.rect;
			float height = ((Rect)(ref rect)).height;
			rect = viewport.rect;
			float num = height - ((Rect)(ref rect)).height;
			if (!(num <= 0f))
			{
				scroll.StopMovement();
				scroll.verticalNormalizedPosition = Mathf.Clamp01(scroll.verticalNormalizedPosition + direction * 54f / num);
			}
		}

		private void Update()
		{
			if (!Object.op_Implicit((Object)(object)root) || !root.activeSelf)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				Close();
			}
			else if (settingsGeneration != Plugin.SettingsGeneration || (!saved && !frozen && Time.unscaledTime >= nextRefresh))
			{
				if (!frozen)
				{
					snapshot = Plugin.History.Snapshot();
				}
				RefreshItems();
				nextRefresh = Time.unscaledTime + 0.25f;
			}
		}

		private void SelectTab(bool value)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			saved = value;
			content.anchoredPosition = Vector2.zero;
			RefreshItems();
		}

		private void RefreshItems()
		{
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)root))
			{
				string query = search.text ?? string.Empty;
				items = (saved ? Plugin.SavedNames.Select((string name) => new MenuItem(name, string.Empty)) : snapshot.Select((SoundEntry entry) => new MenuItem(entry.Name, entry.Timestamp.ToString("HH:mm:ss")))).Where((MenuItem item) => item.Name.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
				settingsGeneration = Plugin.SettingsGeneration;
				NativeSoundTheme.SetLabel(savedTab, $"Saved sounds ({Plugin.SavedNames.Length})");
				theme.SelectTab(logTab, !saved);
				theme.SelectTab(savedTab, saved);
				((TMP_Text)pageTitle).text = (saved ? "Saved sounds" : "Sound log");
				Button obj = pauseButton;
				bool interactable = (((Selectable)clearButton).interactable = !saved);
				((Selectable)obj).interactable = interactable;
				NativeSoundTheme.SetLabel(pauseButton, frozen ? "Resume log" : "Pause log");
				theme.SetToggle(pauseButton, frozen && !saved);
				theme.SetIcon(pauseButton, frozen ? SoundGlyph.Play : SoundGlyph.Pause);
				theme.SetToggle(clearButton, enabled: false);
				theme.SetToggle(enableButton, Plugin.MutingEnabled);
				theme.SetIcon(enableButton, Plugin.MutingEnabled ? SoundGlyph.Check : SoundGlyph.Off);
				enabledLamp.sprite = (Plugin.MutingEnabled ? theme.Art.LampOn : theme.Art.LampOff);
				((TMP_Text)countLabel).text = (saved ? $"{items.Length} remembered sounds" : $"{items.Length} / {snapshot.Length} recent events");
				((TMP_Text)hint).text = (Plugin.MutingEnabled ? "ON: Your saved sound mutes apply." : "OFF: All sounds can play.");
				((TMP_Text)helper).text = (Plugin.MutingEnabled ? "Turn off to hear all sounds. Your selections are kept." : "Turn on to apply your saved sound mutes.");
				((Component)empty).gameObject.SetActive(items.Length == 0);
				((TMP_Text)empty).text = (saved ? "No saved sounds match. Mute a sound in the log to remember it here." : "No sounds match yet. Let a sound play, or change your search.");
				rebuilding = true;
				RectTransform obj2 = content;
				Rect rect = viewport.rect;
				obj2.sizeDelta = new Vector2(0f, Mathf.Max(((Rect)(ref rect)).height, (float)items.Length * 54f));
				rebuilding = false;
				firstRow = -1;
				RenderRows();
			}
		}

		private void RenderRows()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (rebuilding || !Object.op_Implicit((Object)(object)content))
			{
				return;
			}
			int num = Mathf.Clamp(Mathf.FloorToInt(content.anchoredPosition.y / 54f), 0, Mathf.Max(0, items.Length - 1));
			if (num != firstRow)
			{
				firstRow = num;
				for (int i = 0; i < rowPool.Count; i++)
				{
					int num2 = num + i;
					rowPool[i].Bind((num2 < items.Length) ? items[num2] : null, num2, saved);
				}
			}
		}

		private void ChangeMute(string name)
		{
			try
			{
				Plugin.SetMuted(name, !Plugin.IsSelectedMuted(name));
				((TMP_Text)status).text = (Plugin.MutingEnabled ? "Saved. Current playback and future sounds updated." : "Saved. Turn on Global Enable to apply your selected mutes.");
			}
			catch (Exception ex)
			{
				((TMP_Text)status).text = "Could not save this change. See LogOutput.log.";
				Plugin.Warn(ex.ToString());
			}
			RefreshItems();
		}

		private void Forget(string name)
		{
			try
			{
				Plugin.RemoveSaved(name);
				((TMP_Text)status).text = "Removed " + name + ". Mute it from the log to add it again.";
			}
			catch (Exception ex)
			{
				((TMP_Text)status).text = "Could not save this change. See LogOutput.log.";
				Plugin.Warn(ex.ToString());
			}
			RefreshItems();
		}

		private void Close()
		{
			if (Object.op_Implicit((Object)(object)root))
			{
				root.SetActive(false);
			}
			inputHold.Release();
		}

		private void OnDisable()
		{
			Close();
		}

		private void OnDestroy()
		{
			Close();
			theme?.Dispose();
		}

		private RectTransform Place(string name, Transform parent, float x, float y, float width, float height)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = theme.Rect(name, parent);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			obj.pivot = val;
			Vector2 anchorMin = (obj.anchorMax = val);
			obj.anchorMin = anchorMin;
			obj.anchoredPosition = new Vector2(x, 0f - y);
			obj.sizeDelta = new Vector2(width, height);
			return obj;
		}

		internal static void Stretch(RectTransform rect)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			Vector2 offsetMin = (rect.offsetMax = Vector2.zero);
			rect.offsetMin = offsetMin;
		}
	}
	public sealed class SoundButtonPress : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
	{
		internal Action? Capture;

		public void OnPointerDown(PointerEventData eventData)
		{
			Capture?.Invoke();
		}
	}
	internal enum SoundGlyph
	{
		Wave,
		Bookmark,
		Search,
		Pause,
		Play,
		Trash,
		Copy,
		Check,
		Off,
		Close,
		Up,
		Down
	}
	internal sealed class SoundMenuArt : IDisposable
	{
		private readonly List<Object> owned = new List<Object>();

		private readonly Dictionary<SoundGlyph, Sprite> icons = new Dictionary<SoundGlyph, Sprite>();

		internal readonly Sprite Window;

		internal readonly Sprite Paper;

		internal readonly Sprite Field;

		internal readonly Sprite List;

		internal readonly Sprite ActiveTab;

		internal readonly Sprite InactiveTab;

		internal readonly Sprite LampOn;

		internal readonly Sprite LampOff;

		internal Sprite this[SoundGlyph glyph] => icons[glyph];

		private static Color32 C(byte r, byte g, byte b)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return new Color32(r, g, b, byte.MaxValue);
		}

		internal SoundMenuArt()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0126: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = C(65, 32, 21);
			Color32 val2 = C(222, 159, 46);
			Color32 val3 = C(byte.MaxValue, 226, 119);
			Window = Frame("Window", C(111, 34, 27), val, val2, val3, val2, C(133, 49, 31));
			Paper = Frame("Page", C(197, 174, 126), val, C(150, 111, 71), C(226, 207, 162));
			Field = Frame("Search", C(220, 199, 153), val, C(242, 220, 170), C(155, 123, 76));
			List = Frame("List", C(195, 172, 126), C(104, 70, 43), C(226, 205, 159));
			ActiveTab = Frame("Active tab", C(235, 204, 128), val, val2, val3, C(197, 137, 42));
			InactiveTab = Frame("Inactive tab", C(161, 137, 84), val, C(175, 128, 43), C(208, 171, 91), C(117, 87, 41));
			LampOn = Frame("Enabled indicator", C(93, 181, 54), val, val2, val3, C(40, 104, 35));
			LampOff = Frame("Disabled indicator", C(124, 86, 65), val, val2, C(183, 147, 86), C(92, 62, 44));
			foreach (SoundGlyph value in Enum.GetValues(typeof(SoundGlyph)))
			{
				icons[value] = Icon(value);
			}
		}

		private Sprite Frame(string name, Color32 fill, params Color32[] border)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[576];
			for (int i = 0; i < 24; i++)
			{
				for (int j = 0; j < 24; j++)
				{
					int num = Math.Min(Math.Min(j, 23 - j), Math.Min(i, 23 - i));
					bool flag = (j < 2 || j >= 22) && (i < 2 || i >= 22) && Math.Min(j, 23 - j) + Math.Min(i, 23 - i) < 2;
					array[i * 24 + j] = (Color32)(flag ? new Color32((byte)0, (byte)0, (byte)0, (byte)0) : ((num < border.Length) ? border[num] : fill));
				}
			}
			return Make(name, array, 24, border.Length + 1);
		}

		private Sprite Icon(SoundGlyph glyph)
		{
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[576];
			bool[] mask = new bool[576];
			switch (glyph)
			{
			case SoundGlyph.Wave:
				Box(3, 9, 2, 6);
				Box(7, 5, 2, 14);
				Box(11, 2, 3, 20);
				Box(16, 6, 2, 12);
				Box(20, 10, 2, 4);
				break;
			case SoundGlyph.Bookmark:
				Box(5, 3, 14, 14);
				Box(5, 17, 5, 4);
				Box(14, 17, 5, 4);
				break;
			case SoundGlyph.Search:
				Box(4, 3, 10, 2);
				Box(2, 5, 2, 8);
				Box(14, 5, 2, 8);
				Box(4, 13, 10, 2);
				Line(14, 14, 1, 1, 7);
				break;
			case SoundGlyph.Pause:
				Box(5, 3, 5, 18);
				Box(14, 3, 5, 18);
				break;
			case SoundGlyph.Play:
			{
				for (int k = 0; k < 9; k++)
				{
					Box(6 + k, 3 + k, 1, 18 - 2 * k);
				}
				break;
			}
			case SoundGlyph.Trash:
				Box(5, 7, 14, 2);
				Box(8, 3, 8, 2);
				Box(3, 5, 18, 2);
				Box(6, 9, 2, 11);
				Box(16, 9, 2, 11);
				Box(8, 19, 8, 2);
				Box(11, 9, 2, 9);
				break;
			case SoundGlyph.Copy:
				Box(4, 3, 12, 2);
				Box(4, 5, 2, 13);
				Box(8, 7, 13, 2);
				Box(8, 9, 2, 13);
				Box(19, 9, 2, 13);
				Box(10, 20, 9, 2);
				Box(12, 12, 5, 2);
				Box(12, 16, 5, 2);
				break;
			case SoundGlyph.Check:
				Line(3, 11, 1, 1, 6);
				Line(9, 15, 1, -1, 12);
				break;
			case SoundGlyph.Off:
				Box(4, 10, 16, 4);
				break;
			case SoundGlyph.Close:
				Line(4, 4, 1, 1, 15);
				Line(4, 18, 1, -1, 15);
				break;
			case SoundGlyph.Up:
			{
				for (int j = 0; j < 8; j++)
				{
					Box(11 - j, 6 + j, 2 + 2 * j, 1);
				}
				break;
			}
			case SoundGlyph.Down:
			{
				for (int i = 0; i < 8; i++)
				{
					Box(4 + i, 9 + i, 16 - 2 * i, 1);
				}
				break;
			}
			}
			for (int l = 0; l < 24; l++)
			{
				for (int m = 0; m < 24; m++)
				{
					bool flag = false;
					for (int n = Math.Max(0, l - 1); n <= Math.Min(23, l + 1); n++)
					{
						for (int num = Math.Max(0, m - 1); num <= Math.Min(23, m + 1); num++)
						{
							flag |= mask[n * 24 + num];
						}
					}
					array[(24 - l - 1) * 24 + m] = (Color32)(mask[l * 24 + m] ? C(byte.MaxValue, 235, 184) : (flag ? C(57, 34, 24) : new Color32((byte)0, (byte)0, (byte)0, (byte)0)));
				}
			}
			return Make(glyph.ToString(), array, 24, 0);
			void Box(int x, int y, int w, int h)
			{
				for (int num2 = y; num2 < y + h; num2++)
				{
					for (int num3 = x; num3 < x + w; num3++)
					{
						if (num3 >= 0 && num3 < 24 && num2 >= 0 && num2 < 24)
						{
							mask[num2 * 24 + num3] = true;
						}
					}
				}
			}
			void Line(int x, int y, int dx, int dy, int count)
			{
				for (int num2 = 0; num2 < count; num2++)
				{
					Box(x + dx * num2, y + dy * num2, 2, 2);
				}
			}
		}

		private Sprite Make(string name, Color32[] pixels, int size, int border)
		{
			//IL_0004: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0053: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				name = "QuietCrafting." + name,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			val.SetPixels32(pixels);
			val.Apply(false, true);
			owned.Add((Object)(object)val);
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)border, (float)border, (float)border, (float)border));
			((Object)val2).name = ((Object)val).name;
			owned.Add((Object)(object)val2);
			return val2;
		}

		public void Dispose()
		{
			for (int num = owned.Count - 1; num >= 0; num--)
			{
				if (Object.op_Implicit(owned[num]))
				{
					Object.Destroy(owned[num]);
				}
			}
			owned.Clear();
		}
	}
	public sealed class SoundMenuButton : Button
	{
		private RectTransform? caption;

		private RectTransform? icon;

		private Vector2 captionPosition;

		private Vector2 iconPosition;

		private float captionOffsetY;

		private bool hasPressedFace;

		private bool latchedPressed;

		internal void BindCaption(RectTransform value, float offsetY, RectTransform? iconRect = null)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			caption = value;
			captionPosition = value.anchoredPosition;
			captionOffsetY = offsetY;
			icon = iconRect;
			if (Object.op_Implicit((Object)(object)icon))
			{
				iconPosition = icon.anchoredPosition;
			}
			PositionCaption();
		}

		internal void SetPressedFace(bool available, bool latched)
		{
			hasPressedFace = available;
			latchedPressed = latched;
			PositionCaption();
		}

		internal void RefreshState()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			((Selectable)this).DoStateTransition(((Selectable)this).currentSelectionState, true);
		}

		protected override void DoStateTransition(SelectionState state, bool instant)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			((Selectable)this).DoStateTransition(state, instant);
			PositionCaption();
		}

		private void PositionCaption()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0043: 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_005a: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)caption))
			{
				float num = ((hasPressedFace && (latchedPressed || (int)((Selectable)this).currentSelectionState == 2)) ? 2f : 0f);
				caption.anchoredPosition = captionPosition + new Vector2(0f, captionOffsetY - num);
				if (Object.op_Implicit((Object)(object)icon))
				{
					icon.anchoredPosition = iconPosition + new Vector2(0f, 0f - num);
				}
			}
		}
	}
}