Decompiled source of PortalNameBoards v0.1.2

plugins/PortalNameBoards/PortalNameBoards.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Blackforge.Hot;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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 Blackforge
{
	public static class Portals
	{
		private class Model
		{
			public List<GameObject> parts = new List<GameObject>();

			public GameObject text;

			public Bounds plank;
		}

		private class Entry
		{
			public GameObject board;

			public TextMeshProUGUI text;

			public Material glow;

			public string shown;
		}

		private const string Board = "bf_portal_name";

		private const string SignPrefab = "sign";

		private static readonly Color Ink = new Color(2.2f, 1.8f, 0.9f, 1f);

		private static readonly Color Halo = new Color(1.5f, 0.8f, 0.2f, 0.8f);

		private static HotHost host;

		private static Model model;

		private static readonly Dictionary<TeleportWorld, Entry> entries = new Dictionary<TeleportWorld, Entry>();

		private static readonly Dictionary<string, float> tops = new Dictionary<string, float>();

		private static bool failed;

		public static void Load(HotHost from)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			host = from;
			host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(TeleportWorld), "UpdatePortal", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Portals), "Update", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void Unload()
		{
			foreach (Entry value in entries.Values)
			{
				if ((Object)(object)value.board != (Object)null)
				{
					Object.Destroy((Object)(object)value.board);
				}
				if ((Object)(object)value.glow != (Object)null)
				{
					Object.Destroy((Object)(object)value.glow);
				}
			}
			entries.Clear();
			tops.Clear();
			model = null;
			failed = false;
			host = null;
		}

		private static void Update(TeleportWorld __instance)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			if (host == null || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
			{
				return;
			}
			try
			{
				if (!entries.TryGetValue(__instance, out var value) || (Object)(object)value.board == (Object)null)
				{
					if (entries.Count > 0)
					{
						List<TeleportWorld> list = new List<TeleportWorld>();
						foreach (KeyValuePair<TeleportWorld, Entry> entry in entries)
						{
							if ((Object)(object)entry.Key == (Object)null || (Object)(object)entry.Value.board == (Object)null)
							{
								list.Add(entry.Key);
							}
						}
						foreach (TeleportWorld item in list)
						{
							entries.Remove(item);
						}
					}
					value = Make(__instance);
					if (value == null)
					{
						return;
					}
					entries[__instance] = value;
				}
				string text = StringExtensionMethods.RemoveRichTextTags(__instance.GetText());
				if (!(text == value.shown))
				{
					value.shown = text;
					((TMP_Text)value.text).text = text;
					host.Log.LogInfo((object)$"portals: the board at {((Component)__instance).transform.position} says '{text}'");
				}
			}
			catch (Exception error)
			{
				Warn(error);
			}
		}

		private static Entry Make(TeleportWorld portal)
		{
			//IL_0074: 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_0081: Expected O, but got Unknown
			//IL_00b3: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			if (model == null)
			{
				model = Fit();
			}
			if ((Object)(object)model.text == (Object)null)
			{
				return null;
			}
			string text = ((Object)((Component)portal).gameObject).name.Split('(')[0].Trim();
			if (!tops.TryGetValue(text, out var value))
			{
				value = Top(portal, text);
				tops[text] = value;
			}
			int layer = ((Component)portal).gameObject.layer;
			GameObject val = new GameObject("bf_portal_name")
			{
				layer = layer
			};
			val.transform.SetParent(((Component)portal).transform, false);
			float num = Rest(portal, value);
			val.transform.localPosition = new Vector3(0f, num - ((Bounds)(ref model.plank)).min.y, 0f);
			foreach (GameObject part in model.parts)
			{
				Object.Instantiate<GameObject>(part, val.transform, false);
			}
			Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>(true);
			Material val2 = Glow(componentInChildren);
			host.Log.LogInfo((object)$"portals: the board of {text} at {((Component)portal).transform.position} rests at {num:0.00} m, the model is {value:0.00} m high, its text glows with {((Object)val2.shader).name}, halo {val2.HasProperty(ShaderUtilities.ID_GlowColor)}");
			return new Entry
			{
				board = val,
				text = componentInChildren,
				glow = val2,
				shown = null
			};
		}

		private static Material Glow(TextMeshProUGUI text)
		{
			//IL_0001: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			((Graphic)text).color = Color.white;
			((TMP_Text)text).outlineWidth = 0f;
			Material fontMaterial = ((TMP_Text)text).fontMaterial;
			fontMaterial.SetColor(ShaderUtilities.ID_FaceColor, Ink);
			fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0f);
			fontMaterial.EnableKeyword(ShaderUtilities.Keyword_Glow);
			fontMaterial.SetColor(ShaderUtilities.ID_GlowColor, Halo);
			fontMaterial.SetFloat(ShaderUtilities.ID_GlowOffset, 0f);
			fontMaterial.SetFloat(ShaderUtilities.ID_GlowInner, 0.3f);
			fontMaterial.SetFloat(ShaderUtilities.ID_GlowOuter, 0.6f);
			fontMaterial.SetFloat(ShaderUtilities.ID_GlowPower, 0.8f);
			((TMP_Text)text).UpdateMeshPadding();
			return fontMaterial;
		}

		private static Model Fit()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			Model model = new Model();
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("sign") : null);
			Sign val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Sign>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.m_textWidget == (Object)null)
			{
				host.Log.LogWarning((object)"portals: the game has no sign with a text, portals get no board");
				return model;
			}
			Transform transform = val.transform;
			Transform val3 = ((TMP_Text)val2.m_textWidget).transform;
			while ((Object)(object)val3.parent != (Object)(object)transform)
			{
				val3 = val3.parent;
			}
			model.text = ((Component)val3).gameObject;
			List<string> list = new List<string>();
			bool flag = false;
			foreach (Transform item in transform)
			{
				Transform val4 = item;
				if (((Object)val4).name.StartsWith("_snappoint"))
				{
					continue;
				}
				model.parts.Add(((Component)val4).gameObject);
				list.Add(((Object)val4).name);
				MeshFilter[] componentsInChildren = ((Component)val4).GetComponentsInChildren<MeshFilter>(false);
				foreach (MeshFilter val5 in componentsInChildren)
				{
					if (!((Object)(object)val5.sharedMesh == (Object)null) && !((Object)(object)((Component)val5).GetComponent<MeshRenderer>() == (Object)null))
					{
						Bounds val6 = Box(transform, val5);
						if (!flag)
						{
							model.plank = val6;
							flag = true;
						}
						((Bounds)(ref model.plank)).Encapsulate(val6);
					}
				}
			}
			if (!flag)
			{
				model.plank = new Bounds(Vector3.zero, Vector3.one);
			}
			host.Log.LogInfo((object)string.Format("portals: the board is a {0} of {1:0.00} by {2:0.00} by {3:0.00} m, parts {4}", "sign", ((Bounds)(ref model.plank)).size.x, ((Bounds)(ref model.plank)).size.y, ((Bounds)(ref model.plank)).size.z, string.Join(", ", list)));
			return model;
		}

		private static float Top(TeleportWorld portal, string prefab)
		{
			//IL_0081: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null);
			Transform val2 = (((Object)(object)val != (Object)null) ? val.transform : ((Component)portal).transform);
			bool flag = false;
			float num = 0f;
			MeshFilter[] componentsInChildren = ((Component)val2).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val3 in componentsInChildren)
			{
				if (!((Object)(object)val3.sharedMesh == (Object)null) && !((Object)(object)((Component)val3).GetComponent<MeshRenderer>() == (Object)null) && Shown(((Component)val3).transform, val2))
				{
					Bounds val4 = Box(val2, val3);
					float y = ((Bounds)(ref val4)).max.y;
					num = (flag ? Mathf.Max(num, y) : y);
					flag = true;
				}
			}
			if (!flag)
			{
				num = 3f;
			}
			host.Log.LogInfo((object)$"portals: the model of {prefab} is {num:0.00} m high");
			return num;
		}

		private static float Rest(TeleportWorld portal, float top)
		{
			//IL_001e: 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_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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)portal).transform;
			float num = float.MinValue;
			for (int i = 0; i < 11; i++)
			{
				float num2 = ((Bounds)(ref model.plank)).min.x + ((Bounds)(ref model.plank)).size.x * (float)i / 10f;
				RaycastHit[] array = Physics.RaycastAll(transform.TransformPoint(new Vector3(num2, top + 2f, 0f)), -transform.up, top + 4f, -1, (QueryTriggerInteraction)1);
				for (int j = 0; j < array.Length; j++)
				{
					RaycastHit val = array[j];
					if (((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(transform))
					{
						num = Mathf.Max(num, transform.InverseTransformPoint(((RaycastHit)(ref val)).point).y);
					}
				}
			}
			if (num != float.MinValue)
			{
				return num;
			}
			return top;
		}

		private static bool Shown(Transform part, Transform root)
		{
			Transform val = part;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				if (!((Component)val).gameObject.activeSelf)
				{
					return false;
				}
				val = val.parent;
			}
			return true;
		}

		private static Bounds Box(Transform root, MeshFilter filter)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 val = root.worldToLocalMatrix * ((Component)filter).transform.localToWorldMatrix;
			Bounds bounds = filter.sharedMesh.bounds;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(((Matrix4x4)(ref val)).MultiplyPoint3x4(((Bounds)(ref bounds)).min), Vector3.zero);
			for (int i = 0; i < 8; i++)
			{
				((Bounds)(ref result)).Encapsulate(((Matrix4x4)(ref val)).MultiplyPoint3x4(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3(((i & 1) == 0) ? (-1f) : 1f, ((i & 2) == 0) ? (-1f) : 1f, ((i & 4) == 0) ? (-1f) : 1f))));
			}
			return result;
		}

		private static void Warn(Exception error)
		{
			if (!failed && host != null)
			{
				failed = true;
				host.Log.LogWarning((object)$"portals: a board failed, said only once: {error}");
			}
		}
	}
	[BepInPlugin("vladasz.portalnameboards", "Portal Name Boards", "0.1.2")]
	public class PortalNameBoardsPlugin : BaseUnityPlugin
	{
		public const string Id = "vladasz.portalnameboards";

		public const string Number = "0.1.2";

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			HotHost hotHost = new HotHost(((BaseUnityPlugin)this).Logger, new Harmony("vladasz.portalnameboards"), "0.1.2");
			if (!hotHost.IsDedicatedServer)
			{
				Portals.Load(hotHost);
			}
		}
	}
}
namespace Blackforge.Hot
{
	public sealed class HotHost
	{
		public ManualLogSource Log { get; }

		public Harmony Harmony { get; }

		public string Version { get; }

		public bool IsDedicatedServer => (int)SystemInfo.graphicsDeviceType == 4;

		internal HotHost(ManualLogSource log, Harmony harmony, string version)
		{
			Log = log;
			Harmony = harmony;
			Version = version;
		}

		public byte[] ReadAsset(string relative)
		{
			return File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(typeof(HotHost).Assembly.Location), relative));
		}

		public void UnregisterRpc(IEnumerable<string> names)
		{
			if (ZRoutedRpc.instance == null)
			{
				return;
			}
			foreach (string name in names)
			{
				ZRoutedRpc.instance.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name));
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}