Decompiled source of ChestLabels v0.4.1

BepInEx/plugins/chamberland_chest_label.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
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.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 ChamberLand
{
	[BepInPlugin("ChamberLand.chest_label", "Chest Label", "0.4.0")]
	[BepInProcess("valheim.exe")]
	public class chest_label : BaseUnityPlugin
	{
		private sealed class ColorConfig
		{
			private readonly ConfigEntry<float> _r;

			private readonly ConfigEntry<float> _g;

			private readonly ConfigEntry<float> _b;

			private readonly ConfigEntry<float> _a;

			public Color Value => new Color(_r.Value / 255f, _g.Value / 255f, _b.Value / 255f, _a.Value);

			public ColorConfig(ConfigFile cfg, string section, string prefix, float r, float g, float b, float a)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Expected O, but got Unknown
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Expected O, but got Unknown
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Expected O, but got Unknown
				_r = cfg.Bind<float>(section, prefix + "_Red", r, new ConfigDescription("Red: 0-255", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 255f), Array.Empty<object>()));
				_g = cfg.Bind<float>(section, prefix + "_Green", g, new ConfigDescription("Green: 0-255", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 255f), Array.Empty<object>()));
				_b = cfg.Bind<float>(section, prefix + "_Blue", b, new ConfigDescription("Blue: 0-255", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 255f), Array.Empty<object>()));
				_a = cfg.Bind<float>(section, prefix + "_Alpha", a, new ConfigDescription("Alpha/Opacity: 0-1", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			}
		}

		private sealed class LabelReceiver : TextReceiver
		{
			private readonly ZNetView _nview;

			public LabelReceiver(ZNetView nview)
			{
				_nview = nview;
			}

			public string GetText()
			{
				return ((Object)(object)_nview != (Object)null && _nview.GetZDO() != null) ? _nview.GetZDO().GetString("ChamberLand.chest_label", "") : "";
			}

			public void SetText(string text)
			{
				SetLabel(_nview, text?.Trim());
			}
		}

		[HarmonyPatch(typeof(Container), "Interact")]
		private static class Container_Interact_Patch
		{
			private static bool Prefix(Container __instance, ref bool __result)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (!Input.GetKey(p_modifierKey.Value))
				{
					return true;
				}
				if ((Object)(object)((Component)__instance).GetComponent<TombStone>() != (Object)null)
				{
					return true;
				}
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || component.GetZDO() == null)
				{
					return true;
				}
				TextInput.instance.RequestText((TextReceiver)(object)new LabelReceiver(component), "Chest label", p_maxLength.Value);
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "Awake")]
		private static class Container_Awake_Patch
		{
			private static void Postfix(Container __instance)
			{
				if ((Object)(object)Instance != (Object)null)
				{
					((MonoBehaviour)Instance).StartCoroutine(RefreshNextFrame(__instance));
				}
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		private static class Container_GetHoverText_Patch
		{
			private static void Postfix(Container __instance, ref string __result)
			{
				string label = GetLabel(__instance);
				if (!string.IsNullOrEmpty(label) && !__result.Contains(label))
				{
					string text = Localization.instance.Localize(__instance.m_name);
					if (!string.IsNullOrEmpty(text) && __result.Contains(text))
					{
						__result = __result.Replace(text, label);
					}
					else
					{
						__result = label + "\n" + __result;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverName")]
		private static class Container_GetHoverName_Patch
		{
			private static void Postfix(Container __instance, ref string __result)
			{
				string label = GetLabel(__instance);
				if (!string.IsNullOrEmpty(label))
				{
					__result = label;
				}
			}
		}

		public const string ModGuid = "ChamberLand.chest_label";

		public const string ModName = "Chest Label";

		public const string ModVersion = "0.4.0";

		public const string ZdoKey = "ChamberLand.chest_label";

		private const string FrontChildName = "ChamberLand_label_front";

		private const string LeftChildName = "ChamberLand_label_left";

		private const string RightChildName = "ChamberLand_label_right";

		private const string BackChildName = "ChamberLand_label_back";

		private readonly Harmony _harmony = new Harmony("ChamberLand.chest_label");

		internal static ManualLogSource Log;

		internal static chest_label Instance;

		private static ConfigEntry<KeyCode> p_modifierKey;

		private static ConfigEntry<int> p_maxLength;

		private static ConfigEntry<bool> p_showFront;

		private static ConfigEntry<bool> p_showLeft;

		private static ConfigEntry<bool> p_showRight;

		private static ConfigEntry<bool> p_showBack;

		private static ConfigEntry<float> p_maxTextSize;

		private static ColorConfig p_labelColor;

		private static TMP_FontAsset s_font;

		private void Awake()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			p_modifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("00-General", "modifierKey", (KeyCode)306, "Hold this key and press E (interact) on a chest to edit its label");
			p_maxLength = ((BaseUnityPlugin)this).Config.Bind<int>("00-General", "maxLabelLength", 32, new ConfigDescription("Maximum label length", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 64), Array.Empty<object>()));
			p_showFront = ((BaseUnityPlugin)this).Config.Bind<bool>("01-Display", "showFront", true, "Render the label on the chest's front face");
			p_showLeft = ((BaseUnityPlugin)this).Config.Bind<bool>("01-Display", "showLeft", true, "Render the label on the chest's left side");
			p_showRight = ((BaseUnityPlugin)this).Config.Bind<bool>("01-Display", "showRight", true, "Render the label on the chest's right side");
			p_showBack = ((BaseUnityPlugin)this).Config.Bind<bool>("01-Display", "showBack", false, "Render the label on the chest's back");
			p_maxTextSize = ((BaseUnityPlugin)this).Config.Bind<float>("01-Display", "maxTextSize", 1.6f, new ConfigDescription("Upper bound for auto-sized label text (world units)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
			p_labelColor = new ColorConfig(((BaseUnityPlugin)this).Config, "02-Label Color", "p_labelColor", 255f, 220f, 150f, 1f);
			try
			{
				_harmony.PatchAll();
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("Harmony patching failed - {0} is inactive:\n{1}", "Chest Label", arg));
			}
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}

		internal static string GetLabel(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return "";
			}
			ZNetView component = ((Component)container).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return "";
			}
			return component.GetZDO().GetString("ChamberLand.chest_label", "");
		}

		private static void SetLabel(ZNetView nview, string text)
		{
			if (!((Object)(object)nview == (Object)null) && nview.GetZDO() != null)
			{
				nview.ClaimOwnership();
				nview.GetZDO().Set("ChamberLand.chest_label", text ?? "");
				RefreshLabelDisplay(((Component)nview).GetComponent<Container>());
			}
		}

		private static IEnumerator RefreshNextFrame(Container container)
		{
			yield return null;
			RefreshLabelDisplay(container);
		}

		internal static void RefreshLabelDisplay(Container container)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0138: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_01e0: 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_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: 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_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: 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_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null)
			{
				return;
			}
			string label = GetLabel(container);
			Transform val = ((Component)container).transform.Find("ChamberLand_label_front");
			Transform val2 = ((Component)container).transform.Find("ChamberLand_label_left");
			Transform val3 = ((Component)container).transform.Find("ChamberLand_label_right");
			Transform val4 = ((Component)container).transform.Find("ChamberLand_label_back");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			if ((Object)(object)val3 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			if ((Object)(object)val4 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
			if (!string.IsNullOrEmpty(label))
			{
				Bounds val5 = LocalBounds(container);
				if (p_showFront.Value)
				{
					Vector3 localPos = ((Bounds)(ref val5)).center + new Vector3(0f, 0f, ((Bounds)(ref val5)).extents.z + 0.02f);
					Quaternion localRot = Quaternion.Euler(0f, 180f, 0f);
					Vector2 faceSize = default(Vector2);
					((Vector2)(ref faceSize))..ctor(((Bounds)(ref val5)).size.x, ((Bounds)(ref val5)).size.y);
					MakeText(((Component)container).transform, "ChamberLand_label_front", label, localPos, localRot, faceSize);
				}
				if (p_showBack.Value)
				{
					Vector3 localPos2 = ((Bounds)(ref val5)).center - new Vector3(0f, 0f, ((Bounds)(ref val5)).extents.z + 0.02f);
					Quaternion identity = Quaternion.identity;
					Vector2 faceSize2 = default(Vector2);
					((Vector2)(ref faceSize2))..ctor(((Bounds)(ref val5)).size.x, ((Bounds)(ref val5)).size.y);
					MakeText(((Component)container).transform, "ChamberLand_label_back", label, localPos2, identity, faceSize2);
				}
				Vector2 faceSize3 = default(Vector2);
				((Vector2)(ref faceSize3))..ctor(((Bounds)(ref val5)).size.z, ((Bounds)(ref val5)).size.y);
				if (p_showRight.Value)
				{
					Vector3 localPos3 = ((Bounds)(ref val5)).center + new Vector3(((Bounds)(ref val5)).extents.x + 0.02f, 0f, 0f);
					MakeText(((Component)container).transform, "ChamberLand_label_right", label, localPos3, Quaternion.Euler(0f, -90f, 0f), faceSize3);
				}
				if (p_showLeft.Value)
				{
					Vector3 localPos4 = ((Bounds)(ref val5)).center - new Vector3(((Bounds)(ref val5)).extents.x + 0.02f, 0f, 0f);
					MakeText(((Component)container).transform, "ChamberLand_label_left", label, localPos4, Quaternion.Euler(0f, 90f, 0f), faceSize3);
				}
			}
		}

		private static void MakeText(Transform parent, string childName, string label, Vector3 localPos, Quaternion localRot, Vector2 faceSize)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001c: 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_007f: 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_00a9: 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)
			GameObject val = new GameObject(childName);
			val.transform.SetParent(parent, false);
			val.transform.localPosition = localPos;
			val.transform.localRotation = localRot;
			TextMeshPro val2 = val.AddComponent<TextMeshPro>();
			TMP_FontAsset val3 = FindFont();
			if ((Object)(object)val3 != (Object)null)
			{
				((TMP_Text)val2).font = val3;
			}
			else if (Log != null)
			{
				Log.LogWarning((object)"No TMP font found in game resources - labels may log fallback warnings");
			}
			((TMP_Text)val2).text = label;
			((Graphic)val2).color = p_labelColor.Value;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(faceSize.x * 0.9f, faceSize.y * 0.6f);
			((TMP_Text)val2).enableAutoSizing = true;
			((TMP_Text)val2).fontSizeMin = 0.05f;
			((TMP_Text)val2).fontSizeMax = p_maxTextSize.Value;
			((TMP_Text)val2).enableWordWrapping = false;
		}

		private static TMP_FontAsset FindFont()
		{
			if ((Object)(object)s_font != (Object)null)
			{
				return s_font;
			}
			TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			s_font = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null && ((Object)f).name.Contains("Averia"))) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null));
			if ((Object)(object)s_font != (Object)null && Log != null)
			{
				Log.LogDebug((object)("Chest labels using font: " + ((Object)s_font).name));
			}
			return s_font;
		}

		private static Bounds LocalBounds(Container container)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_013e: 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_005f: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)container).transform;
			bool flag = true;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(Vector3.zero, Vector3.one * 0.5f);
			MeshFilter[] componentsInChildren = ((Component)container).GetComponentsInChildren<MeshFilter>();
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val2 = ((Bounds)(ref bounds)).center + new Vector3(((Bounds)(ref bounds)).extents.x * (((j & 1) == 0) ? (-1f) : 1f), ((Bounds)(ref bounds)).extents.y * (((j & 2) == 0) ? (-1f) : 1f), ((Bounds)(ref bounds)).extents.z * (((j & 4) == 0) ? (-1f) : 1f));
					Vector3 val3 = transform.InverseTransformPoint(((Component)val).transform.TransformPoint(val2));
					if (flag)
					{
						((Bounds)(ref result))..ctor(val3, Vector3.zero);
						flag = false;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val3);
					}
				}
			}
			return result;
		}
	}
}